From 7ef79d3f4b02e3d2e71d6888fbedd9b3f9c325c7 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 11 Jul 2013 11:19:57 -0400 Subject: [PATCH 01/69] Remove non-portable and unnused header includes --- gtk2_ardour/about.cc | 1 - libs/ardour/audio_diskstream.cc | 2 -- libs/ardour/audiosource.cc | 1 - libs/ardour/diskstream.cc | 1 - libs/ardour/midi_clock_slave.cc | 1 - libs/ardour/midi_diskstream.cc | 1 - libs/ardour/midi_source.cc | 1 - libs/ardour/mtc_slave.cc | 1 - libs/ardour/session_butler.cc | 10 ---------- libs/ardour/session_midi.cc | 2 -- libs/ardour/session_state.cc | 6 ------ libs/ardour/sndfilesource.cc | 2 -- libs/ardour/source.cc | 2 -- libs/pbd/sndfile_manager.cc | 1 - 14 files changed, 32 deletions(-) diff --git a/gtk2_ardour/about.cc b/gtk2_ardour/about.cc index 280f72a8dc..6255bfa108 100644 --- a/gtk2_ardour/about.cc +++ b/gtk2_ardour/about.cc @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index c302e06681..7bfc9426cd 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include "pbd/error.h" #include "pbd/xml++.h" diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 74dd52d504..e11fe1c4fa 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index a359f228e8..6ef4327343 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -29,7 +29,6 @@ #include #include #include -#include #include diff --git a/libs/ardour/midi_clock_slave.cc b/libs/ardour/midi_clock_slave.cc index 6f54d17d02..8906ddb6c4 100644 --- a/libs/ardour/midi_clock_slave.cc +++ b/libs/ardour/midi_clock_slave.cc @@ -20,7 +20,6 @@ #include #include -#include #include #include #include "pbd/error.h" diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 9c11e818ac..a21f3fb6f4 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -28,7 +28,6 @@ #include #include // for ffs(3) #include -#include #include "pbd/error.h" #include "pbd/basename.h" diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index 124d3f7c9b..1887b74302 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index 8ce0722d8b..14ca928905 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -19,7 +19,6 @@ */ #include #include -#include #include #include diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index 1d235b051a..3e7c2226cc 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -17,16 +17,6 @@ */ -#include -#include -#include -#include -#include -#include -#include - -#include - #include "pbd/error.h" #include "pbd/pthread_utils.h" #include "pbd/stacktrace.h" diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 50a7178f1b..9feaa1fb2b 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -22,8 +22,6 @@ #include #include #include -#include -#include #include diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 49a0eed559..ff7da665ed 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -33,17 +33,11 @@ #include #include #include -#include -#include #include -#include #include #ifdef HAVE_SYS_VFS_H #include -#else -#include -#include #endif #ifdef HAVE_SYS_STATVFS_H diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index cf75cffba3..f29682aeaa 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -26,8 +26,6 @@ #include #include -#include -#include #include #include diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index 618dddc70b..03039fea5b 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -19,8 +19,6 @@ #include #include -#include -#include #include #include #include diff --git a/libs/pbd/sndfile_manager.cc b/libs/pbd/sndfile_manager.cc index d1dcd05256..c028bc11ba 100644 --- a/libs/pbd/sndfile_manager.cc +++ b/libs/pbd/sndfile_manager.cc @@ -22,7 +22,6 @@ */ #include -#include #include #include #include From 4be2176bd900d3ffc685e585c5f435e8f51db4f6 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 11 Jul 2013 11:23:41 -0400 Subject: [PATCH 02/69] Revert "Remove non-portable and unnused header includes" This reverts commit 7ef79d3f4b02e3d2e71d6888fbedd9b3f9c325c7. --- gtk2_ardour/about.cc | 1 + libs/ardour/audio_diskstream.cc | 2 ++ libs/ardour/audiosource.cc | 1 + libs/ardour/diskstream.cc | 1 + libs/ardour/midi_clock_slave.cc | 1 + libs/ardour/midi_diskstream.cc | 1 + libs/ardour/midi_source.cc | 1 + libs/ardour/mtc_slave.cc | 1 + libs/ardour/session_butler.cc | 10 ++++++++++ libs/ardour/session_midi.cc | 2 ++ libs/ardour/session_state.cc | 6 ++++++ libs/ardour/sndfilesource.cc | 2 ++ libs/ardour/source.cc | 2 ++ libs/pbd/sndfile_manager.cc | 1 + 14 files changed, 32 insertions(+) diff --git a/gtk2_ardour/about.cc b/gtk2_ardour/about.cc index 6255bfa108..280f72a8dc 100644 --- a/gtk2_ardour/about.cc +++ b/gtk2_ardour/about.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 7bfc9426cd..c302e06681 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "pbd/error.h" #include "pbd/xml++.h" diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index e11fe1c4fa..74dd52d504 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index 6ef4327343..a359f228e8 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include diff --git a/libs/ardour/midi_clock_slave.cc b/libs/ardour/midi_clock_slave.cc index 8906ddb6c4..6f54d17d02 100644 --- a/libs/ardour/midi_clock_slave.cc +++ b/libs/ardour/midi_clock_slave.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include #include "pbd/error.h" diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index a21f3fb6f4..9c11e818ac 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -28,6 +28,7 @@ #include #include // for ffs(3) #include +#include #include "pbd/error.h" #include "pbd/basename.h" diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index 1887b74302..124d3f7c9b 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index 14ca928905..8ce0722d8b 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -19,6 +19,7 @@ */ #include #include +#include #include #include diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index 3e7c2226cc..1d235b051a 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -17,6 +17,16 @@ */ +#include +#include +#include +#include +#include +#include +#include + +#include + #include "pbd/error.h" #include "pbd/pthread_utils.h" #include "pbd/stacktrace.h" diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 9feaa1fb2b..50a7178f1b 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index ff7da665ed..49a0eed559 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -33,11 +33,17 @@ #include #include #include +#include +#include #include +#include #include #ifdef HAVE_SYS_VFS_H #include +#else +#include +#include #endif #ifdef HAVE_SYS_STATVFS_H diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index f29682aeaa..cf75cffba3 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index 03039fea5b..618dddc70b 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include diff --git a/libs/pbd/sndfile_manager.cc b/libs/pbd/sndfile_manager.cc index c028bc11ba..d1dcd05256 100644 --- a/libs/pbd/sndfile_manager.cc +++ b/libs/pbd/sndfile_manager.cc @@ -22,6 +22,7 @@ */ #include +#include #include #include #include From bd9e2737b7acefd6be7c409b5d41797d386cc08f Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 11 Jul 2013 14:50:33 +0200 Subject: [PATCH 03/69] NOOP - prevent headaches and remove cruft Every "point zero one" seconds is only 25 Hz in ardour.. --- gtk2_ardour/ardour_ui.cc | 7 +++---- gtk2_ardour/ardour_ui.h | 12 +++++++++--- gtk2_ardour/ardour_ui_dialogs.cc | 5 ++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 77fab156bb..3bd2768a4c 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -898,8 +898,7 @@ If you still wish to quit, please use the\n\n\ second_connection.disconnect (); point_one_second_connection.disconnect (); - point_oh_five_second_connection.disconnect (); - point_zero_one_second_connection.disconnect(); + point_zero_something_second_connection.disconnect(); } delete ARDOUR_UI::instance()->video_timeline; @@ -1029,9 +1028,9 @@ ARDOUR_UI::every_point_one_seconds () } gint -ARDOUR_UI::every_point_zero_one_seconds () +ARDOUR_UI::every_point_zero_something_seconds () { - // august 2007: actual update frequency: 40Hz, not 100Hz + // august 2007: actual update frequency: 25Hz (40ms), not 100Hz SuperRapidScreenUpdate(); /* EMIT_SIGNAL */ return TRUE; diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index dd025b6f8b..5817293b29 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -177,10 +177,17 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr static PublicEditor* _instance; static sigc::signal Blink; + + /** point_zero_one_seconds -- 10Hz ^= 100ms */ static sigc::signal RapidScreenUpdate; + + /** point_zero_something_seconds -- currently 25Hz ^= 40ms */ static sigc::signal SuperRapidScreenUpdate; + /** Emitted frequently with the audible frame, false, and the edit point as * parameters respectively. + * + * (either RapidScreenUpdate || SuperRapidScreenUpdate - user-config) */ static sigc::signal Clock; @@ -521,12 +528,11 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr gint every_second (); gint every_point_one_seconds (); - gint every_point_zero_one_seconds (); + gint every_point_zero_something_seconds (); sigc::connection second_connection; sigc::connection point_one_second_connection; - sigc::connection point_oh_five_second_connection; - sigc::connection point_zero_one_second_connection; + sigc::connection point_zero_something_second_connection; void open_session (); void open_recent_session (); diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 5422bb9957..8c78d6494d 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -183,7 +183,7 @@ ARDOUR_UI::set_session (Session *s) second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000); point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100); - point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40); + point_zero_something_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_something_seconds), 40); update_format (); } @@ -223,8 +223,7 @@ ARDOUR_UI::unload_session (bool hide_stuff) second_connection.disconnect (); point_one_second_connection.disconnect (); - point_oh_five_second_connection.disconnect (); - point_zero_one_second_connection.disconnect(); + point_zero_something_second_connection.disconnect(); ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false); From c33cabeb828d673f2298c0894ebf1b1d3ad79218 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 11 Jul 2013 14:54:28 +0200 Subject: [PATCH 04/69] update plugin UIs at reasonable rate (25Hz) --- gtk2_ardour/generic_pluginui.cc | 2 +- gtk2_ardour/lv2_plugin_ui.cc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index 52bb468a67..72273f512a 100644 --- a/gtk2_ardour/generic_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -836,7 +836,7 @@ GenericPluginUI::start_updating (GdkEventAny*) { if (output_controls.size() > 0 ) { screen_update_connection.disconnect(); - screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect + screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &GenericPluginUI::output_update)); } return false; diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc index 839bc6a4b8..2fe817a6a0 100644 --- a/gtk2_ardour/lv2_plugin_ui.cc +++ b/gtk2_ardour/lv2_plugin_ui.cc @@ -144,7 +144,7 @@ LV2PluginUI::start_updating(GdkEventAny*) { if (!_output_ports.empty()) { _screen_update_connection.disconnect(); - _screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect + _screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &LV2PluginUI::output_update)); } return false; @@ -322,7 +322,7 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title) if (_lv2->has_message_output()) { _lv2->enable_ui_emmission(); - ARDOUR_UI::instance()->RapidScreenUpdate.connect( + ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect( sigc::mem_fun(*this, &LV2PluginUI::update_timeout)); } } @@ -432,7 +432,7 @@ LV2PluginUI::on_window_show(const std::string& title) LV2_EXTERNAL_UI_SHOW(_external_ui_ptr); _screen_update_connection.disconnect(); - _screen_update_connection = ARDOUR_UI::instance()->RapidScreenUpdate.connect + _screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &LV2PluginUI::output_update)); return false; } else { From 75f0dfb4a8b7b15dff83b3af3ecaa15f78f6de2b Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 11 Jul 2013 15:44:35 +0200 Subject: [PATCH 05/69] fix compiler warning --- libs/gtkmm2ext/gtkmm2ext/dndvbox.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gtkmm2ext/gtkmm2ext/dndvbox.h b/libs/gtkmm2ext/gtkmm2ext/dndvbox.h index bc5ca6c725..bbfd183c7b 100644 --- a/libs/gtkmm2ext/gtkmm2ext/dndvbox.h +++ b/libs/gtkmm2ext/gtkmm2ext/dndvbox.h @@ -351,7 +351,7 @@ private: /* dropped from ourselves onto ourselves */ - T* child = *((T **) selection_data.get_data()); + T* child = *((T * const *) selection_data.get_data()); if (drop.first == 0) { _internal_vbox.reorder_child (child->widget(), -1); From 56daf0b54f735d728bb04a115125b3a790357bc6 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 11 Jul 2013 15:52:08 +0200 Subject: [PATCH 06/69] change default color of plugin-UI gauge/meter --- gtk2_ardour/generic_pluginui.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index 72273f512a..0233b1192f 100644 --- a/gtk2_ardour/generic_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -671,7 +671,17 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptrmeterinfo = info; - info->meter = new FastMeter (5, 5, FastMeter::Vertical); + info->meter = new FastMeter ( + 5, 5, FastMeter::Vertical, 0, + 0x0000aaff, + 0x008800ff, 0x008800ff, + 0x00ff00ff, 0x00ff00ff, + 0xcccc00ff, 0xcccc00ff, + 0xffaa00ff, 0xffaa00ff, + 0xff0000ff, + ARDOUR_UI::config()->canvasvar_MeterBackgroundBot.get(), + ARDOUR_UI::config()->canvasvar_MeterBackgroundTop.get() + ); info->min_unbound = desc.min_unbound; info->max_unbound = desc.max_unbound; From 66763688d53516f3745cc5f214fe585cd30f3792 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 11 Jul 2013 16:42:26 +0200 Subject: [PATCH 07/69] make config-window suitable for small[er] screens --- gtk2_ardour/configinfo.cc | 10 ++++++++-- gtk2_ardour/configinfo.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/gtk2_ardour/configinfo.cc b/gtk2_ardour/configinfo.cc index 29c7e8fe63..67f13a1f5b 100644 --- a/gtk2_ardour/configinfo.cc +++ b/gtk2_ardour/configinfo.cc @@ -31,9 +31,15 @@ ConfigInfoDialog::ConfigInfoDialog () text.get_buffer()->set_text (std::string (ARDOUR::ardour_config_info)); text.set_wrap_mode (Gtk::WRAP_WORD); text.show (); - text.set_size_request (300, 800); - get_vbox()->pack_start (text, true, true); + scroller.set_shadow_type(Gtk::SHADOW_NONE); + scroller.set_border_width(0); + scroller.add (text); + scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + scroller.show(); + + get_vbox()->pack_start (scroller, true, true); + set_size_request (400, 600); add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_ACCEPT); } diff --git a/gtk2_ardour/configinfo.h b/gtk2_ardour/configinfo.h index 84f90b20a2..209392a8f1 100644 --- a/gtk2_ardour/configinfo.h +++ b/gtk2_ardour/configinfo.h @@ -18,6 +18,7 @@ */ #include +#include #include "ardour_dialog.h" @@ -28,4 +29,5 @@ class ConfigInfoDialog : public ArdourDialog private: Gtk::TextView text; + Gtk::ScrolledWindow scroller; }; From da79e702e461eca8f3b3f082227dce26592317b0 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 11 Jul 2013 20:38:52 +0200 Subject: [PATCH 08/69] clean up plugin-ui meter layout --- gtk2_ardour/generic_pluginui.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc index 0233b1192f..971dfc0e9b 100644 --- a/gtk2_ardour/generic_pluginui.cc +++ b/gtk2_ardour/generic_pluginui.cc @@ -661,7 +661,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptrdisplay_label->set_name ("ParameterValueDisplay"); control_ui->display->add (*control_ui->display_label); - Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->display, "-99,99", 2, 2); + Gtkmm2ext::set_size_request_to_display_given_text (*control_ui->display, "-888.8g", 2, 6); control_ui->display->show_all (); @@ -692,6 +692,9 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptrvbox = manage (new VBox); control_ui->hbox = manage (new HBox); + control_ui->hbox->set_spacing(1); + control_ui->vbox->set_spacing(3); + control_ui->label.set_angle(90); control_ui->hbox->pack_start (control_ui->label, false, false); control_ui->hbox->pack_start (*info->meter, false, false); From 2a0440a37349b01d5b339dcd46e22d3f9cf85a2d Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 12 Jul 2013 12:47:12 +0200 Subject: [PATCH 09/69] remove *&@?!+%@ question :) I would like to record, edit and mix,... ..but I don't need software to hold my hand and ask childish questions if I would like to "open a session". --- gtk2_ardour/startup.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk2_ardour/startup.cc b/gtk2_ardour/startup.cc index 6f0b1cfaab..ca598ba949 100644 --- a/gtk2_ardour/startup.cc +++ b/gtk2_ardour/startup.cc @@ -591,7 +591,7 @@ ArdourStartup::setup_initial_choice_page () ic_vbox.show_all (); initial_choice_index = append_page (ic_vbox); - set_page_title (ic_vbox, _("What would you like to do ?")); + set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING)); set_page_header_image (ic_vbox, icon_pixbuf); /* user could just click on "Forward" if default From e0bbc0b435eb93ea2e1e2a61453a0639ac10071c Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 12 Jul 2013 17:56:42 +0200 Subject: [PATCH 10/69] minor peak-meter performance tweak * redraw only missing parts of the outside rectangle, * don't redraw RMS meter if value has not changed --- libs/gtkmm2ext/fastmeter.cc | 17 +++++------------ libs/gtkmm2ext/gtkmm2ext/fastmeter.h | 1 - 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/libs/gtkmm2ext/fastmeter.cc b/libs/gtkmm2ext/fastmeter.cc index 4819609878..c0bcb05af5 100644 --- a/libs/gtkmm2ext/fastmeter.cc +++ b/libs/gtkmm2ext/fastmeter.cc @@ -53,7 +53,6 @@ FastMeter::FastMeter (long hold, unsigned long dimen, Orientation o, int len, { orientation = o; hold_cnt = hold; - resized = true; hold_state = 0; bright_hold = false; current_peak = 0; @@ -353,7 +352,6 @@ FastMeter::on_size_allocate (Gtk::Allocation &alloc) } DrawingArea::on_size_allocate (alloc); - resized = true; } bool @@ -372,16 +370,13 @@ FastMeter::vertical_expose (GdkEventExpose* ev) cairo_t* cr = gdk_cairo_create (get_window ()->gobj()); - if (resized) { - cairo_set_source_rgb (cr, 0, 0, 0); // black - rounded_rectangle (cr, 0, 0, pixrect.width + 2, pixheight + 2, 2); - cairo_stroke (cr); - //cairo_fill (cr); - //resized = false; - } cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height); cairo_clip (cr); + cairo_set_source_rgb (cr, 0, 0, 0); // black + rounded_rectangle (cr, 0, 0, pixrect.width + 2, pixheight + 2, 2); + cairo_stroke (cr); + top_of_meter = (gint) floor (pixheight * current_level); /* reset the height & origin of the rect that needs to show the pixbuf @@ -464,11 +459,10 @@ FastMeter::set (float lvl, float peak) current_level = lvl; - if (current_level == old_level && current_peak == old_peak && hold_state == 0) { + if (current_level == old_level && current_peak == old_peak && (hold_state == 0 || peak != -1)) { return; } - Glib::RefPtr win; if ((win = get_window()) == 0) { @@ -565,7 +559,6 @@ FastMeter::set_highlight (bool onoff) } highlight = onoff; bgpattern = request_vertical_background (request_width, pixheight, highlight ? _bgh : _bgc, highlight); - resized = true; queue_draw (); } diff --git a/libs/gtkmm2ext/gtkmm2ext/fastmeter.h b/libs/gtkmm2ext/gtkmm2ext/fastmeter.h index debe6c1cc7..f065020a57 100644 --- a/libs/gtkmm2ext/gtkmm2ext/fastmeter.h +++ b/libs/gtkmm2ext/gtkmm2ext/fastmeter.h @@ -91,7 +91,6 @@ private: float current_level; float current_peak; float current_user_level; - bool resized; bool highlight; bool vertical_expose (GdkEventExpose*); From 5bae4373c792481980a1e9a986627f90af4ea520 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 12 Jul 2013 19:07:07 +0200 Subject: [PATCH 11/69] implement visual-sensitivity (gray out) for faders Note: bar-controller sensitivity state is not yet set if automation-mode changes to/from play, but the widget now supports that. --- libs/gtkmm2ext/barcontroller.cc | 6 ++++++ libs/gtkmm2ext/pixfader.cc | 16 +++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc index 50c21e57e7..693151aaed 100644 --- a/libs/gtkmm2ext/barcontroller.cc +++ b/libs/gtkmm2ext/barcontroller.cc @@ -468,6 +468,12 @@ BarController::expose (GdkEventExpose* /*event*/) break; } + if (!darea.get_sensitive()) { + rounded_rectangle (context, 0, 0, darea.get_width(), darea.get_height(), 3); + context->set_source_rgba (0.505, 0.517, 0.525, 0.6); + context->fill (); + } + /* draw label */ double xpos = -1; diff --git a/libs/gtkmm2ext/pixfader.cc b/libs/gtkmm2ext/pixfader.cc index 6e0c642917..0185550259 100644 --- a/libs/gtkmm2ext/pixfader.cc +++ b/libs/gtkmm2ext/pixfader.cc @@ -292,13 +292,15 @@ PixFader::on_expose_event (GdkEventExpose* ev) pango_cairo_show_layout (cr, _layout->gobj()); } -// if (Config->get_widget_prelight()) { //pixfader does not have access to config - if (_hovering) { - Gtkmm2ext::rounded_rectangle (cr, 0, 0, get_width(), get_height(), 3); - cairo_set_source_rgba (cr, 0.905, 0.917, 0.925, 0.1); - cairo_fill (cr); - } -// } + if (!get_sensitive()) { + Gtkmm2ext::rounded_rectangle (cr, 0, 0, get_width(), get_height(), 3); + cairo_set_source_rgba (cr, 0.505, 0.517, 0.525, 0.4); + cairo_fill (cr); + } else if (_hovering) { + Gtkmm2ext::rounded_rectangle (cr, 0, 0, get_width(), get_height(), 3); + cairo_set_source_rgba (cr, 0.905, 0.917, 0.925, 0.1); + cairo_fill (cr); + } last_drawn = ds; From ff825cd8bdc1aaddee6b31977b554a1fc3e04029 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:19:03 -0400 Subject: [PATCH 12/69] Include pbd/localtime_r.h for mingw build --- gtk2_ardour/midi_tracer.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gtk2_ardour/midi_tracer.cc b/gtk2_ardour/midi_tracer.cc index 70d7c24da6..1fc50c103f 100644 --- a/gtk2_ardour/midi_tracer.cc +++ b/gtk2_ardour/midi_tracer.cc @@ -23,6 +23,8 @@ #include #include +#include "pbd/localtime_r.h" + #include "midi++/parser.h" #include "midi++/manager.h" From aa4dd3443ffd3cb4639c69dc72214a3f5b758071 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:19:32 -0400 Subject: [PATCH 13/69] Include pbd/timersub.h for mingw build --- gtk2_ardour/midi_tracer.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/gtk2_ardour/midi_tracer.cc b/gtk2_ardour/midi_tracer.cc index 1fc50c103f..e447c59f3b 100644 --- a/gtk2_ardour/midi_tracer.cc +++ b/gtk2_ardour/midi_tracer.cc @@ -24,6 +24,7 @@ #include #include "pbd/localtime_r.h" +#include "pbd/timersub.h" #include "midi++/parser.h" #include "midi++/manager.h" From 745501b6f3ad93cda419d2d9f56d212e34b80c17 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:20:01 -0400 Subject: [PATCH 14/69] Fix for small identifier being defined on windows/mingw --- gtk2_ardour/panner2d.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gtk2_ardour/panner2d.cc b/gtk2_ardour/panner2d.cc index 64d83ab162..395cd2f5dd 100644 --- a/gtk2_ardour/panner2d.cc +++ b/gtk2_ardour/panner2d.cc @@ -390,7 +390,7 @@ Panner2d::on_expose_event (GdkEventExpose *event) { CartesianVector c; cairo_t* cr; - bool small = (height <= large_size_threshold); + bool small_size = (height <= large_size_threshold); const double diameter = radius*2.0; cr = gdk_cairo_create (get_window()->gobj()); @@ -473,7 +473,7 @@ Panner2d::on_expose_event (GdkEventExpose *event) cairo_select_font_face (cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - if (small) { + if (small_size) { arc_radius = 4.0; } else { cairo_set_font_size (cr, 10); @@ -498,10 +498,10 @@ Panner2d::on_expose_event (GdkEventExpose *event) cairo_set_source_rgba (cr, 0.517, 0.772, 0.882, 1.0); cairo_stroke (cr); - if (!small && !signal->text.empty()) { + if (!small_size && !signal->text.empty()) { cairo_set_source_rgb (cr, 0.517, 0.772, 0.882); /* the +/- adjustments are a hack to try to center the text in the circle */ - if (small) { + if (small_size) { cairo_move_to (cr, c.x - 1, c.y + 1); } else { cairo_move_to (cr, c.x - 4, c.y + 4); @@ -535,7 +535,7 @@ Panner2d::on_expose_event (GdkEventExpose *event) cairo_move_to (cr, c.x, c.y); cairo_save (cr); cairo_rotate (cr, -(speaker->position.azi/360.0) * (2.0 * M_PI)); - if (small) { + if (small_size) { cairo_scale (cr, 0.8, 0.8); } else { cairo_scale (cr, 1.2, 1.2); @@ -553,7 +553,7 @@ Panner2d::on_expose_event (GdkEventExpose *event) cairo_fill (cr); cairo_restore (cr); - if (!small) { + if (!small_size) { cairo_set_font_size (cr, 16); /* move the text in just a bit */ From a0ada1f233acc153f92e86e3cb73d34b009c82d0 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:20:45 -0400 Subject: [PATCH 15/69] Assume no filesystem links on windows --- gtk2_ardour/sfdb_ui.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index e8db9d4939..482a3b61b7 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -1463,6 +1463,9 @@ SoundFileOmega::check_info (const vector& paths, bool& same_size, bool& bool SoundFileOmega::check_link_status (const Session* s, const vector& paths) { +#ifdef WIN32 + return false; +#else std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest")); bool ret = false; @@ -1492,6 +1495,7 @@ SoundFileOmega::check_link_status (const Session* s, const vector& paths out: rmdir (tmpdir.c_str()); return ret; +#endif } SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s) From eddcc868ba7786a7039edd1a96acbcac83499007 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:26:54 -0400 Subject: [PATCH 16/69] Disable non-realtime midi ports in windows build - THIS NEEDS FIXING --- libs/ardour/midi_ui.cc | 2 ++ libs/midi++2/jack_midi_port.cc | 6 ++++++ libs/midi++2/midi++/jack_midi_port.h | 10 +++++++++- libs/midi++2/midi++/port.h | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/libs/ardour/midi_ui.cc b/libs/ardour/midi_ui.cc index 78da32e427..82261b58ec 100644 --- a/libs/ardour/midi_ui.cc +++ b/libs/ardour/midi_ui.cc @@ -104,7 +104,9 @@ MidiControlUI::midi_input_handler (IOCondition ioc, MIDI::Port* port) if (ioc & IO_IN) { +#ifndef WIN32 CrossThreadChannel::drain (port->selectable()); +#endif DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", port->name())); framepos_t now = _session.engine().frame_time(); diff --git a/libs/midi++2/jack_midi_port.cc b/libs/midi++2/jack_midi_port.cc index 57ca2b3629..3220ca5b55 100644 --- a/libs/midi++2/jack_midi_port.cc +++ b/libs/midi++2/jack_midi_port.cc @@ -58,7 +58,9 @@ JackMIDIPort::JackMIDIPort (string const & name, Flags flags, jack_client_t* jac , _last_write_timestamp (0) , output_fifo (512) , input_fifo (1024) +#ifndef WIN32 , xthread (true) +#endif { assert (jack_client); init (name, flags); @@ -73,7 +75,9 @@ JackMIDIPort::JackMIDIPort (const XMLNode& node, jack_client_t* jack_client) , _last_write_timestamp (0) , output_fifo (512) , input_fifo (1024) +#ifndef WIN32 , xthread (true) +#endif { assert (jack_client); @@ -170,7 +174,9 @@ JackMIDIPort::cycle_start (pframes_t nframes) } if (event_count) { +#ifndef WIN32 xthread.wakeup (); +#endif } } } diff --git a/libs/midi++2/midi++/jack_midi_port.h b/libs/midi++2/midi++/jack_midi_port.h index a8859387a4..f91c7dab83 100644 --- a/libs/midi++2/midi++/jack_midi_port.h +++ b/libs/midi++2/midi++/jack_midi_port.h @@ -57,7 +57,13 @@ class JackMIDIPort : public Port { int write (const byte *msg, size_t msglen, timestamp_t timestamp); int read (byte *buf, size_t bufsize); void drain (int check_interval_usecs); - int selectable () const { return xthread.selectable(); } + int selectable () const { +#ifdef WIN32 + return false; +#else + return xthread.selectable(); +#endif + } pframes_t nframes_this_cycle() const { return _nframes_this_cycle; } @@ -80,7 +86,9 @@ private: RingBuffer< Evoral::Event > output_fifo; Evoral::EventRingBuffer input_fifo; Glib::Threads::Mutex output_fifo_lock; +#ifndef WIN32 CrossThreadChannel xthread; +#endif int create_port (); diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index 439760115c..d4f03b593e 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -27,7 +27,9 @@ #include #include "pbd/xml++.h" +#ifndef WIN32 #include "pbd/crossthread.h" +#endif #include "pbd/signals.h" #include "pbd/ringbuffer.h" From 5dca8270eb589cc60c756e09bd02ce323805b741 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:27:56 -0400 Subject: [PATCH 17/69] Use PBD::GlibSemaphore on windows to signal peak --- gtk2_ardour/audio_region_editor.cc | 30 ++++++++++++++++++++++++++---- gtk2_ardour/audio_region_editor.h | 10 ++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/audio_region_editor.cc b/gtk2_ardour/audio_region_editor.cc index 2aeb2dbe60..03d3e47264 100644 --- a/gtk2_ardour/audio_region_editor.cc +++ b/gtk2_ardour/audio_region_editor.cc @@ -54,7 +54,9 @@ AudioRegionEditor::AudioRegionEditor (Session* s, boost::shared_ptr : RegionEditor (s, r) , _audio_region (r) , gain_adjustment(accurate_coefficient_to_dB(_audio_region->scale_amplitude()), -40.0, +40.0, 0.1, 1.0, 0) +#ifndef WIN32 , _peak_channel (false) +#endif { Gtk::HBox* b = Gtk::manage (new Gtk::HBox); @@ -91,7 +93,7 @@ AudioRegionEditor::AudioRegionEditor (Session* s, boost::shared_ptr PeakAmplitudeFound.connect (_peak_amplitude_connection, invalidator (*this), boost::bind (&AudioRegionEditor::peak_amplitude_found, this, _1), gui_context ()); pthread_create_and_store (X_("peak-amplitude"), &_peak_amplitude_thread_handle, _peak_amplitude_thread, this); - _peak_channel.deliver ('c'); + signal_peak_thread (); } AudioRegionEditor::~AudioRegionEditor () @@ -112,7 +114,7 @@ AudioRegionEditor::region_changed (const PBD::PropertyChange& what_changed) if (what_changed.contains (ARDOUR::Properties::start) || what_changed.contains (ARDOUR::Properties::length)) { /* ask the peak thread to run again */ - _peak_channel.deliver ('c'); + signal_peak_thread (); } } void @@ -133,13 +135,33 @@ AudioRegionEditor::gain_adjustment_changed () } } +void +AudioRegionEditor::signal_peak_thread () +{ +#ifdef WIN32 + m_peak_sem.post (); +#else + _peak_channel.deliver ('c'); +#endif +} + +void +AudioRegionEditor::wait_for_signal () +{ +#ifdef WIN32 + m_peak_sem.wait (); +#else + char msg; + _peak_channel.receive (msg); +#endif +} + void AudioRegionEditor::peak_amplitude_thread () { while (1) { /* await instructions to run */ - char msg; - _peak_channel.receive (msg); + wait_for_signal (); /* compute peak amplitude and signal the fact */ PeakAmplitudeFound (accurate_coefficient_to_dB (_audio_region->maximum_amplitude ())); /* EMIT SIGNAL */ diff --git a/gtk2_ardour/audio_region_editor.h b/gtk2_ardour/audio_region_editor.h index dd65a3fb31..0d9292b483 100644 --- a/gtk2_ardour/audio_region_editor.h +++ b/gtk2_ardour/audio_region_editor.h @@ -37,7 +37,11 @@ #include #include "pbd/signals.h" +#ifdef WIN32 +#include "pbd/glib_semaphore.h" +#else #include "pbd/crossthread.h" +#endif #include "audio_clock.h" #include "ardour_dialog.h" @@ -74,11 +78,17 @@ class AudioRegionEditor : public RegionEditor Gtk::Label _peak_amplitude_label; Gtk::Entry _peak_amplitude; + void signal_peak_thread (); + void wait_for_signal (); pthread_t _peak_amplitude_thread_handle; void peak_amplitude_found (double); PBD::Signal1 PeakAmplitudeFound; PBD::ScopedConnection _peak_amplitude_connection; +#ifdef WIN32 + PBD::GlibSemaphore m_peak_sem; +#else CrossThreadChannel _peak_channel; +#endif }; #endif /* __gtk_ardour_audio_region_edit_h__ */ From 9db936ac26ae1cca325e0158e33fa7f0fff8eb7e Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:30:27 -0400 Subject: [PATCH 18/69] Don't call pango_ft2* functions on windows --- gtk2_ardour/utils.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index eb3f4ab55d..66f87abd9c 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -707,7 +707,9 @@ set_pango_fontsize () /* FT2 rendering - used by GnomeCanvas, sigh */ +#ifndef WIN32 pango_ft2_font_map_set_resolution ((PangoFT2FontMap*) pango_ft2_font_map_new(), val/1024, val/1024); +#endif /* Cairo rendering, in case there is any */ From 18b50193854dc07bb392651c4708032c5c701345 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:38:17 -0400 Subject: [PATCH 19/69] disable pingback on win32, until we have a replacement for utsname stuff (system ID) --- gtk2_ardour/pingback.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gtk2_ardour/pingback.cc b/gtk2_ardour/pingback.cc index dea7f52f01..ccec81cba7 100644 --- a/gtk2_ardour/pingback.cc +++ b/gtk2_ardour/pingback.cc @@ -23,7 +23,10 @@ #include #include +#ifndef WIN32 #include +#endif + #include #include @@ -70,6 +73,7 @@ struct ping_call { static void* _pingback (void *arg) { +#ifndef WIN32 ping_call* cm = static_cast (arg); CURL* c; struct utsname utb; @@ -158,6 +162,8 @@ _pingback (void *arg) curl_easy_cleanup (c); delete cm; +#endif /* WIN32 */ + return 0; } From ad89d1e0311c556256ac76509e25f72e035290fc Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:44:58 -0400 Subject: [PATCH 20/69] Use custom comparator in threadmap for pthread impl with mingw --- libs/pbd/pbd/abstract_ui.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libs/pbd/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h index fb09dee5c2..905074c474 100644 --- a/libs/pbd/pbd/abstract_ui.h +++ b/libs/pbd/pbd/abstract_ui.h @@ -56,8 +56,22 @@ class AbstractUI : public BaseUI , ui (uir) {} }; typedef typename RequestBuffer::rw_vector RequestBufferVector; + +#if defined(__MINGW32__) + + struct pthread_cmp + { + bool operator() (const ptw32_handle_t& thread1, const ptw32_handle_t& thread2) + { + return thread1.p < thread2.p; + } + }; + typedef typename std::map::iterator RequestBufferMapIterator; + typedef std::map RequestBufferMap; +#else typedef typename std::map::iterator RequestBufferMapIterator; typedef std::map RequestBufferMap; +#endif RequestBufferMap request_buffers; static Glib::Threads::Private per_thread_request_buffer; From 40f49b85ac00d6f36985bda4b87fc5db45ed4433 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 08:45:27 -0400 Subject: [PATCH 21/69] Work around DELETE defined via windows.h --- gtk2_ardour/patch_change_dialog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk2_ardour/patch_change_dialog.cc b/gtk2_ardour/patch_change_dialog.cc index 2ecfd4bdd7..081604344c 100644 --- a/gtk2_ardour/patch_change_dialog.cc +++ b/gtk2_ardour/patch_change_dialog.cc @@ -117,7 +117,7 @@ PatchChangeDialog::PatchChangeDialog ( add_button (Stock::CANCEL, RESPONSE_CANCEL); add_button (ok, RESPONSE_ACCEPT); if (allow_delete) { - add_button (Stock::DELETE, RESPONSE_REJECT); + add_button (Gtk::StockID(GTK_STOCK_DELETE), RESPONSE_REJECT); } set_default_response (RESPONSE_ACCEPT); From cb9b1801ec4ef5974bc9365c1b551a864615a5cc Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 13 Jul 2013 14:58:23 +0200 Subject: [PATCH 22/69] ignore mouse-scroll if scroll-bar is not present. fixes http://tracker.ardour.org/view.php?id=5557 --- gtk2_ardour/meterbridge.cc | 2 ++ gtk2_ardour/mixer_ui.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/gtk2_ardour/meterbridge.cc b/gtk2_ardour/meterbridge.cc index 74c13f45eb..227f533a18 100644 --- a/gtk2_ardour/meterbridge.cc +++ b/gtk2_ardour/meterbridge.cc @@ -309,6 +309,7 @@ Meterbridge::on_scroll_event (GdkEventScroll* ev) void Meterbridge::scroll_left () { + if (!scroller.get_hscrollbar()) return; Adjustment* adj = scroller.get_hscrollbar()->get_adjustment(); /* stupid GTK: can't rely on clamping across versions */ scroller.get_hscrollbar()->set_value (max (adj->get_lower(), adj->get_value() - adj->get_step_increment())); @@ -317,6 +318,7 @@ Meterbridge::scroll_left () void Meterbridge::scroll_right () { + if (!scroller.get_hscrollbar()) return; Adjustment* adj = scroller.get_hscrollbar()->get_adjustment(); /* stupid GTK: can't rely on clamping across versions */ scroller.get_hscrollbar()->set_value (min (adj->get_upper(), adj->get_value() + adj->get_step_increment())); diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index f206014eea..be43a3d6a0 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -1666,6 +1666,7 @@ Mixer_UI::pane_allocation_handler (Allocation&, Gtk::Paned* which) void Mixer_UI::scroll_left () { + if (!scroller.get_hscrollbar()) return; Adjustment* adj = scroller.get_hscrollbar()->get_adjustment(); /* stupid GTK: can't rely on clamping across versions */ scroller.get_hscrollbar()->set_value (max (adj->get_lower(), adj->get_value() - adj->get_step_increment())); @@ -1674,6 +1675,7 @@ Mixer_UI::scroll_left () void Mixer_UI::scroll_right () { + if (!scroller.get_hscrollbar()) return; Adjustment* adj = scroller.get_hscrollbar()->get_adjustment(); /* stupid GTK: can't rely on clamping across versions */ scroller.get_hscrollbar()->set_value (min (adj->get_upper(), adj->get_value() + adj->get_step_increment())); From 57066732ca4289bfb44650e49da32c87085287f0 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 16:43:50 -0400 Subject: [PATCH 23/69] Use pthread_name instead of pthread_self for portability --- libs/ardour/ltc_slave.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/ardour/ltc_slave.cc b/libs/ardour/ltc_slave.cc index 8d08fd6bb5..e9be71d98e 100644 --- a/libs/ardour/ltc_slave.cc +++ b/libs/ardour/ltc_slave.cc @@ -19,11 +19,11 @@ */ #include #include -#include #include #include #include "pbd/error.h" +#include "pbd/pthread_utils.h" #include "ardour/debug.h" #include "ardour/slave.h" @@ -432,7 +432,7 @@ LTC_Slave::speed_and_position (double& speed, framepos_t& pos) frameoffset_t skip = now - (monotonic_cnt + nframes); monotonic_cnt = now; - DEBUG_TRACE (DEBUG::LTC, string_compose ("speed_and_position - TID:%1 | latency: %2 | skip %3\n", ::pthread_self(), ltc_slave_latency.max, skip)); + DEBUG_TRACE (DEBUG::LTC, string_compose ("speed_and_position - TID:%1 | latency: %2 | skip %3\n", pthread_name(), ltc_slave_latency.max, skip)); if (last_timestamp == 0) { engine_dll_initstate = 0; From 3be0f0aa0bc8f9c20e0204ba8b7b03d78b425f5f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 16:44:03 -0400 Subject: [PATCH 24/69] Use pthread_name instead of pthread_self for portability --- libs/ardour/mtc_slave.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index 14ca928905..db98664292 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -23,6 +23,7 @@ #include #include "pbd/error.h" +#include "pbd/pthread_utils.h" #include "midi++/port.h" #include "ardour/debug.h" @@ -305,7 +306,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now) a locate command via MMC. */ - //DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", ::pthread_self())); + //DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", pthread_name())); TimecodeFormat tc_format; bool reset_tc = true; @@ -421,7 +422,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now) now, timecode, mtc_frame, was_full, speedup_due_to_tc_mismatch)); if (was_full || outside_window (mtc_frame)) { - DEBUG_TRACE (DEBUG::MTC, string_compose ("update_mtc_time: full TC or outside window. - TID:%1\n", ::pthread_self())); + DEBUG_TRACE (DEBUG::MTC, string_compose ("update_mtc_time: full TC or outside window. - TID:%1\n", pthread_name())); session.request_locate (mtc_frame, false); session.request_transport_speed (0); update_mtc_status (MIDI::MTC_Stopped); @@ -485,7 +486,7 @@ MTC_Slave::update_mtc_status (MIDI::MTC_Status status) /* XXX !!! thread safety ... called from MIDI I/O context * on locate (via ::update_mtc_time()) */ - DEBUG_TRACE (DEBUG::MTC, string_compose("MTC_Slave::update_mtc_status - TID:%1\n", ::pthread_self())); + DEBUG_TRACE (DEBUG::MTC, string_compose("MTC_Slave::update_mtc_status - TID:%1\n", pthread_name())); return; // why was this fn needed anyway ? it just messes up things -> use reset. busy_guard1++; From 48f8863b2cb5ad4628ff6eef33cb8796e4773068 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 16:44:37 -0400 Subject: [PATCH 25/69] Use g_mkstemp in audiographer for portability --- libs/audiographer/audiographer/sndfile/tmp_file.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/audiographer/audiographer/sndfile/tmp_file.h b/libs/audiographer/audiographer/sndfile/tmp_file.h index 8655fd7191..facb872abf 100644 --- a/libs/audiographer/audiographer/sndfile/tmp_file.h +++ b/libs/audiographer/audiographer/sndfile/tmp_file.h @@ -4,6 +4,9 @@ #include #include +#include +#include + #include "sndfile_writer.h" #include "sndfile_reader.h" @@ -18,7 +21,7 @@ class TmpFile : public SndfileWriter, public SndfileReader /// \a filename_template must match the requirements for mkstemp, i.e. end in "XXXXXX" TmpFile (char * filename_template, int format, ChannelCount channels, framecnt_t samplerate) - : SndfileHandle (mkstemp(filename_template), true, SndfileBase::ReadWrite, format, channels, samplerate) + : SndfileHandle (g_mkstemp(filename_template), true, SndfileBase::ReadWrite, format, channels, samplerate) , filename (filename_template) {} From 550eeecc63eb4a20fcff0799e9ab7e7ac9b7a294 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 16:44:59 -0400 Subject: [PATCH 26/69] Add header include required by mingw compiler --- libs/pbd/pbd/floating.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/pbd/pbd/floating.h b/libs/pbd/pbd/floating.h index 105a976637..6daef5d4aa 100644 --- a/libs/pbd/pbd/floating.h +++ b/libs/pbd/pbd/floating.h @@ -26,6 +26,8 @@ #ifndef __libpbd__floating_h__ #define __libpbd__floating_h__ +#include + #include namespace PBD { From ccdc6fcd6af6a5daa76fe5205acfe6c340673d80 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 16:55:40 -0400 Subject: [PATCH 27/69] Add DEBUG_TRACE output to file utility functions in libpbd --- libs/pbd/debug.cc | 1 + libs/pbd/file_utils.cc | 28 +++++++++++++++++++--------- libs/pbd/pbd/debug.h | 1 + 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/libs/pbd/debug.cc b/libs/pbd/debug.cc index 51d4d1e871..fba457c83e 100644 --- a/libs/pbd/debug.cc +++ b/libs/pbd/debug.cc @@ -49,6 +49,7 @@ uint64_t PBD::DEBUG::FileManager = PBD::new_debug_bit ("filemanager"); uint64_t PBD::DEBUG::Pool = PBD::new_debug_bit ("pool"); uint64_t PBD::DEBUG::EventLoop = PBD::new_debug_bit ("eventloop"); uint64_t PBD::DEBUG::AbstractUI = PBD::new_debug_bit ("abstractui"); +uint64_t PBD::DEBUG::FileUtils = PBD::new_debug_bit ("fileutils"); uint64_t PBD::debug_bits = 0x0; diff --git a/libs/pbd/file_utils.cc b/libs/pbd/file_utils.cc index 01c2fe286a..1a32377ff6 100644 --- a/libs/pbd/file_utils.cc +++ b/libs/pbd/file_utils.cc @@ -35,6 +35,7 @@ #include "pbd/compose.h" #include "pbd/file_utils.h" +#include "pbd/debug.h" #include "pbd/error.h" #include "pbd/pathscanner.h" #include "pbd/stl_delete.h" @@ -80,6 +81,11 @@ find_matching_files_in_directory (const std::string& directory, std::string full_path(directory); full_path = Glib::build_filename (full_path, *file_iter); + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found file %1\n", full_path) + ); + result.push_back(full_path); } } @@ -117,24 +123,28 @@ find_file_in_search_path(const SearchPath& search_path, if (tmp.size() == 0) { + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("No file matching %1 found in Path: %2\n", filename, search_path.to_string()) + ); return false; } -#if 0 if (tmp.size() != 1) { - info << string_compose - ( - "Found more than one file matching %1 in search path %2", - filename, - search_path () - ) - << endmsg; + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found more that one file matching %1 in Path: %2\n", filename, search_path.to_string()) + ); } -#endif result = tmp.front(); + DEBUG_TRACE ( + DEBUG::FileUtils, + string_compose("Found file %1 in Path: %2\n", filename, search_path.to_string()) + ); + return true; } diff --git a/libs/pbd/pbd/debug.h b/libs/pbd/pbd/debug.h index 989cd42dd1..704c9d0dad 100644 --- a/libs/pbd/pbd/debug.h +++ b/libs/pbd/pbd/debug.h @@ -43,6 +43,7 @@ namespace PBD { extern uint64_t Pool; extern uint64_t EventLoop; extern uint64_t AbstractUI; + extern uint64_t FileUtils; } } From 1fd2412f5be9a96e5015f81d5c89d88ce730f9c1 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 16:56:12 -0400 Subject: [PATCH 28/69] Add config/data filesystem paths to search on windows --- libs/ardour/filesystem_paths.cc | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/libs/ardour/filesystem_paths.cc b/libs/ardour/filesystem_paths.cc index 73bfaff137..4c7e996e46 100644 --- a/libs/ardour/filesystem_paths.cc +++ b/libs/ardour/filesystem_paths.cc @@ -86,14 +86,30 @@ user_config_directory () std::string ardour_dll_directory () { +#ifdef WIN32 + std::string dll_dir_path(g_win32_get_package_installation_directory_of_module(NULL)); + dll_dir_path = Glib::build_filename (dll_dir_path, "lib"); + return Glib::build_filename (dll_dir_path, "ardour3"); +#else std::string s = Glib::getenv("ARDOUR_DLL_PATH"); if (s.empty()) { std::cerr << _("ARDOUR_DLL_PATH not set in environment - exiting\n"); ::exit (1); } return s; +#endif } +#ifdef WIN32 +SearchPath +windows_search_path () +{ + std::string dll_dir_path(g_win32_get_package_installation_directory_of_module(NULL)); + dll_dir_path = Glib::build_filename (dll_dir_path, "share"); + return Glib::build_filename (dll_dir_path, "ardour3"); +} +#endif + SearchPath ardour_config_search_path () { @@ -101,7 +117,9 @@ ardour_config_search_path () if (search_path.empty()) { search_path += user_config_directory(); - +#ifdef WIN32 + search_path += windows_search_path (); +#else std::string s = Glib::getenv("ARDOUR_CONFIG_PATH"); if (s.empty()) { std::cerr << _("ARDOUR_CONFIG_PATH not set in environment - exiting\n"); @@ -109,6 +127,7 @@ ardour_config_search_path () } search_path += SearchPath (s); +#endif } return search_path; @@ -121,7 +140,9 @@ ardour_data_search_path () if (search_path.empty()) { search_path += user_config_directory(); - +#ifdef WIN32 + search_path += windows_search_path (); +#else std::string s = Glib::getenv("ARDOUR_DATA_PATH"); if (s.empty()) { std::cerr << _("ARDOUR_DATA_PATH not set in environment - exiting\n"); @@ -129,6 +150,7 @@ ardour_data_search_path () } search_path += SearchPath (s); +#endif } return search_path; From 6542ce76d0740ccd505fd9326a7a4b2d737af663 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 16:57:04 -0400 Subject: [PATCH 29/69] Don't use trylock in assertions on windows as it will fail glib uses TryEnterCriticalSection on windows which will return true if the lock as able to be locked *or* is already locked by the current thread. --- libs/ardour/io.cc | 6 ++++++ libs/ardour/port_insert.cc | 2 ++ libs/ardour/route.cc | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index cdb8a4693c..4e080b06d8 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -395,7 +395,9 @@ IO::disconnect (void* src) int IO::ensure_ports_locked (ChanCount count, bool clear, bool& changed) { +#ifndef WIN32 assert (!AudioEngine::instance()->process_lock().trylock()); +#endif boost::shared_ptr port; @@ -466,7 +468,9 @@ IO::ensure_ports_locked (ChanCount count, bool clear, bool& changed) int IO::ensure_ports (ChanCount count, bool clear, void* src) { +#ifndef WIN32 assert (!AudioEngine::instance()->process_lock().trylock()); +#endif bool changed = false; @@ -501,7 +505,9 @@ IO::ensure_ports (ChanCount count, bool clear, void* src) int IO::ensure_io (ChanCount count, bool clear, void* src) { +#ifndef WIN32 assert (!AudioEngine::instance()->process_lock().trylock()); +#endif return ensure_ports (count, clear, src); } diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc index c13927449a..cf33f1b932 100644 --- a/libs/ardour/port_insert.cc +++ b/libs/ardour/port_insert.cc @@ -250,7 +250,9 @@ PortInsert::signal_latency() const bool PortInsert::configure_io (ChanCount in, ChanCount out) { +#ifndef WIN32 assert (!AudioEngine::instance()->process_lock().trylock()); +#endif /* for an insert, processor input corresponds to IO output, and vice versa */ diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index e87cb4b03f..c6f588a79c 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -1612,7 +1612,9 @@ Route::reset_instrument_info () int Route::configure_processors (ProcessorStreams* err) { +#ifndef WIN32 assert (!AudioEngine::instance()->process_lock().trylock()); +#endif if (!_in_configure_processors) { Glib::Threads::RWLock::WriterLock lm (_processor_lock); @@ -1682,7 +1684,9 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err) int Route::configure_processors_unlocked (ProcessorStreams* err) { +#ifndef WIN32 assert (!AudioEngine::instance()->process_lock().trylock()); +#endif if (_in_configure_processors) { return 0; From e8ecd327326b48655a5e8af69203f7f6587ec4e8 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:00:18 -0400 Subject: [PATCH 30/69] Add test for Glib::Mutex::trylock Behaviour of this method is different on WIN32 --- libs/pbd/test/testrunner.cc | 4 ++++ libs/pbd/wscript | 1 + 2 files changed, 5 insertions(+) diff --git a/libs/pbd/test/testrunner.cc b/libs/pbd/test/testrunner.cc index 1512ebd024..ea8f0aa115 100644 --- a/libs/pbd/test/testrunner.cc +++ b/libs/pbd/test/testrunner.cc @@ -4,11 +4,15 @@ #include #include #include +#include #include "scalar_properties.h" + int main () { + Glib::thread_init(); + ScalarPropertiesTest::make_property_quarks (); CppUnit::TestResult testresult; diff --git a/libs/pbd/wscript b/libs/pbd/wscript index 797f6e2cad..2f93887e62 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -144,6 +144,7 @@ def build(bld): testobj.source = ''' test/testrunner.cc test/xpath.cc + test/mutex_test.cc test/scalar_properties.cc test/signals_test.cc test/convert_test.cc From 2e2c22ad3c0af34b311024b1f8cb4571c1e3c48f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:01:47 -0400 Subject: [PATCH 31/69] Fix saving sessions on windows by using g_rename instead of ::rename --- libs/ardour/session_state.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 7ccaca1a27..b66969176c 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -807,9 +807,9 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot } else { - if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) { - error << string_compose (_("could not rename temporary session file %1 to %2"), - tmp_path, xml_path) << endmsg; + if (g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) { + error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"), + tmp_path, xml_path, g_strerror(errno)) << endmsg; if (g_remove (tmp_path.c_str()) != 0) { error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"), tmp_path, g_strerror (errno)) << endmsg; From 868b06efd65d59af023e37ab63d283c522feb121 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:10:11 -0400 Subject: [PATCH 32/69] Revert "Fix saving sessions on windows by using g_rename instead of ::rename" This reverts commit 2e2c22ad3c0af34b311024b1f8cb4571c1e3c48f. --- libs/ardour/session_state.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index b66969176c..7ccaca1a27 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -807,9 +807,9 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot } else { - if (g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) { - error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"), - tmp_path, xml_path, g_strerror(errno)) << endmsg; + if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) { + error << string_compose (_("could not rename temporary session file %1 to %2"), + tmp_path, xml_path) << endmsg; if (g_remove (tmp_path.c_str()) != 0) { error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"), tmp_path, g_strerror (errno)) << endmsg; From ac16da8ea69482c104ab32bfddb35ab319572216 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:33:30 -0400 Subject: [PATCH 33/69] Fix saving sessions on windows by using g_rename instead of ::rename --- libs/ardour/session_state.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 7ccaca1a27..de573e61b6 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -807,9 +807,9 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot } else { - if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) { - error << string_compose (_("could not rename temporary session file %1 to %2"), - tmp_path, xml_path) << endmsg; + if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) { + error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"), + tmp_path, xml_path, g_strerror(errno)) << endmsg; if (g_remove (tmp_path.c_str()) != 0) { error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"), tmp_path, g_strerror (errno)) << endmsg; From 1bd570c27638d98154dea117a19433e6029b2316 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:39:55 -0400 Subject: [PATCH 34/69] Replace conditional peak debugging with DEBUG_TRACE macro usage Also add some extra debugging info --- libs/ardour/ardour/debug.h | 1 + libs/ardour/audiosource.cc | 88 ++++++++++++-------------------------- libs/ardour/debug.cc | 1 + 3 files changed, 30 insertions(+), 60 deletions(-) diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h index 202d0cc424..ae18e59c04 100644 --- a/libs/ardour/ardour/debug.h +++ b/libs/ardour/ardour/debug.h @@ -34,6 +34,7 @@ namespace PBD { extern uint64_t SnapBBT; extern uint64_t Configuration; extern uint64_t Latency; + extern uint64_t Peaks; extern uint64_t Processors; extern uint64_t ProcessThreads; extern uint64_t Graph; diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index da9be81007..ec2b912357 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -41,6 +41,8 @@ #include "i18n.h" +#include "ardour/debug.h" + using namespace std; using namespace ARDOUR; using namespace PBD; @@ -212,6 +214,8 @@ AudioSource::initialize_peakfile (string audio_path) peakpath = peak_path (audio_path); + DEBUG_TRACE(DEBUG::Peaks, string_compose ("Initialize Peakfile %1 for Audio file %2\n", peakpath, audio_path)); + /* if the peak file should be there, but isn't .... */ if (!empty() && !Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) { @@ -226,7 +230,7 @@ AudioSource::initialize_peakfile (string audio_path) return -1; } - /* peakfile does not exist */ + DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 does not exist\n", peakpath)); _peaks_built = false; @@ -235,7 +239,7 @@ AudioSource::initialize_peakfile (string audio_path) /* we found it in the peaks dir, so check it out */ if (statbuf.st_size == 0 || (statbuf.st_size < (off_t) ((length(_timeline_position) / _FPP) * sizeof (PeakData)))) { - // empty + DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 is empty\n", peakpath)); _peaks_built = false; } else { // Check if the audio file has changed since the peakfile was built. @@ -247,6 +251,7 @@ AudioSource::initialize_peakfile (string audio_path) /* no audio path - nested source or we can't read it or ... whatever, use the peakfile as-is. */ + DEBUG_TRACE(DEBUG::Peaks, string_compose("Error when calling stat on Peakfile %1\n", peakpath)); _peaks_built = true; _peak_byte_max = statbuf.st_size; @@ -325,18 +330,8 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t expected_peaks = (cnt / (double) samples_per_file_peak); scale = npeaks/expected_peaks; -#undef DEBUG_READ_PEAKS -#ifdef DEBUG_READ_PEAKS - cerr << "======>RP: npeaks = " << npeaks - << " start = " << start - << " cnt = " << cnt - << " len = " << _length - << " samples_per_visual_peak =" << samples_per_visual_peak - << " expected was " << expected_peaks << " ... scale = " << scale - << " PD ptr = " << peaks - <RP: npeaks = %1 start = %2 cnt = %3 len = %4 samples_per_visual_peak = %5 expected was %6 ... scale = %7 PD ptr = %8\n" + , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks)); /* fix for near-end-of-file conditions */ @@ -352,9 +347,8 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if (npeaks == cnt) { -#ifdef DEBUG_READ_PEAKS - cerr << "RAW DATA\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "RAW DATA\n"); + /* no scaling at all, just get the sample data and duplicate it for both max and min peak values. */ @@ -388,27 +382,15 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t return -1; } -#ifdef DEBUG_READ_PEAKS - cerr << "DIRECT PEAKS\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n"); #ifndef WIN32 nread = ::pread (peakfile_fd, peaks, sizeof (PeakData)* npeaks, first_peak_byte); #endif if (nread != sizeof (PeakData) * npeaks) { - cerr << "AudioSource[" - << _name - << "]: cannot read peaks from peakfile! (read only " - << nread - << " not " - << npeaks - << "at sample " - << start - << " = byte " - << first_peak_byte - << ')' - << endl; + DEBUG_TRACE (DEBUG::Peaks, string_compose ("[%1]: Cannot read peaks from peakfile! (read only %2 not %3 at sample %4 = byte %5 )\n" + , _name, nread, npeaks, start, first_peak_byte)); delete peakfile_descriptor; return -1; } @@ -426,9 +408,8 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if (scale < 1.0) { -#ifdef DEBUG_READ_PEAKS - cerr << "DOWNSAMPLE\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "DOWNSAMPLE\n"); + /* the caller wants: - more frames-per-peak (lower resolution) than the peakfile, or to put it another way, @@ -475,9 +456,8 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t tnp = min ((framecnt_t)(_length/samples_per_file_peak - current_stored_peak), (framecnt_t) expected_peaks); to_read = min (chunksize, tnp); -#ifdef DEBUG_READ_PEAKS - cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl; -#endif + DEBUG_TRACE (DEBUG::Peaks, string_compose ("reading %1 bytes from peakfile @ %2\n" + , sizeof (PeakData) * to_read, start_byte)); #ifndef WIN32 if ((nread = ::pread (peakfile_fd, staging, sizeof (PeakData) * to_read, start_byte)) @@ -485,20 +465,8 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t off_t fend = lseek (peakfile_fd, 0, SEEK_END); - cerr << "AudioSource[" - << _name - << "]: cannot read peak data from peakfile (" - << (nread / sizeof(PeakData)) - << " peaks instead of " - << to_read - << ") (" - << strerror (errno) - << ')' - << " at start_byte = " << start_byte - << " _length = " << _length << " versus len = " << fend - << " expected maxpeaks = " << (_length - current_frame)/samples_per_file_peak - << " npeaks was " << npeaks - << endl; + DEBUG_TRACE (DEBUG::Peaks, string_compose ("[%1]: cannot read peak data from peakfile (%2 peaks instead of %3) (%4) at start_byte = %5 _length = %6 versus len = %7 expected maxpeaks = %8 npeaks was %9" + , _name, (nread / sizeof(PeakData)), to_read, g_strerror (errno), start_byte, _length, fend, ((_length - current_frame)/samples_per_file_peak), npeaks)); goto out; } #endif @@ -536,9 +504,8 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t } else { -#ifdef DEBUG_READ_PEAKS - cerr << "UPSAMPLE\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n"); + /* the caller wants - less frames-per-peak (more resolution) @@ -627,15 +594,11 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t delete [] staging; delete [] raw_staging; -#ifdef DEBUG_READ_PEAKS - cerr << "RP DONE\n"; -#endif + DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n"); return ret; } -#undef DEBUG_PEAK_BUILD - int AudioSource::build_peaks_from_scratch () { @@ -643,6 +606,8 @@ AudioSource::build_peaks_from_scratch () const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal + DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n"); + int ret = -1; { @@ -692,6 +657,7 @@ AudioSource::build_peaks_from_scratch () out: if (ret) { + DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", peakpath)); unlink (peakpath.c_str()); } @@ -879,6 +845,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize); if (endpos < target_length) { + DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", peakpath)); if (ftruncate (_peakfile_fd, target_length)) { /* error doesn't actually matter so continue on without testing */ } @@ -925,6 +892,7 @@ AudioSource::truncate_peakfile () off_t end = lseek (_peakfile_fd, 0, SEEK_END); if (end > _peak_byte_max) { + DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", peakpath)); if (ftruncate (_peakfile_fd, _peak_byte_max)) { error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"), peakpath, _peak_byte_max, errno) << endmsg; diff --git a/libs/ardour/debug.cc b/libs/ardour/debug.cc index afd5da2169..51115001cb 100644 --- a/libs/ardour/debug.cc +++ b/libs/ardour/debug.cc @@ -31,6 +31,7 @@ uint64_t PBD::DEBUG::MidiDiskstreamIO = PBD::new_debug_bit ("mididiskstreamio"); uint64_t PBD::DEBUG::SnapBBT = PBD::new_debug_bit ("snapbbt"); uint64_t PBD::DEBUG::Configuration = PBD::new_debug_bit ("configuration"); uint64_t PBD::DEBUG::Latency = PBD::new_debug_bit ("latency"); +uint64_t PBD::DEBUG::Peaks = PBD::new_debug_bit ("peaks"); uint64_t PBD::DEBUG::Processors = PBD::new_debug_bit ("processors"); uint64_t PBD::DEBUG::ProcessThreads = PBD::new_debug_bit ("processthreads"); uint64_t PBD::DEBUG::Graph = PBD::new_debug_bit ("graph"); From f754e1c0bbda7917dcfca600fc7ca77a76ea1286 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:40:42 -0400 Subject: [PATCH 35/69] Use boost::scoped_ptr to control scope of peakfile descriptor --- libs/ardour/audiosource.cc | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index ec2b912357..e3f101d9d6 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -30,6 +30,8 @@ #include #include +#include + #include #include @@ -324,7 +326,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t PeakData* staging = 0; Sample* raw_staging = 0; - FdFileDescriptor* peakfile_descriptor = new FdFileDescriptor (peakpath, false, 0664); + boost::scoped_ptr peakfile_descriptor(new FdFileDescriptor (peakpath, false, 0664)); int peakfile_fd = -1; expected_peaks = (cnt / (double) samples_per_file_peak); @@ -365,7 +367,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t peaks[i].min = raw_staging[i]; } - delete peakfile_descriptor; delete [] raw_staging; return 0; } @@ -378,7 +379,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) { error << string_compose(_("AudioSource: cannot open peakpath (a) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - delete peakfile_descriptor; return -1; } @@ -391,7 +391,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if (nread != sizeof (PeakData) * npeaks) { DEBUG_TRACE (DEBUG::Peaks, string_compose ("[%1]: Cannot read peaks from peakfile! (read only %2 not %3 at sample %4 = byte %5 )\n" , _name, nread, npeaks, start, first_peak_byte)); - delete peakfile_descriptor; return -1; } @@ -399,7 +398,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); } - delete peakfile_descriptor; return 0; } @@ -443,7 +441,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) { error << string_compose(_("AudioSource: cannot open peakpath (b) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - delete peakfile_descriptor; delete [] staging; return 0; } @@ -589,8 +586,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t } out: - delete peakfile_descriptor; - delete [] staging; delete [] raw_staging; From b84d032b3a25f6b3522ac179495e927ae886ca48 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:41:48 -0400 Subject: [PATCH 36/69] Use boost::scoped_array in AudioSource::read_peaks --- libs/ardour/audiosource.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index e3f101d9d6..720cb481be 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -324,7 +325,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t framecnt_t zero_fill = 0; int ret = -1; PeakData* staging = 0; - Sample* raw_staging = 0; boost::scoped_ptr peakfile_descriptor(new FdFileDescriptor (peakpath, false, 0664)); int peakfile_fd = -1; @@ -355,9 +355,9 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t both max and min peak values. */ - Sample* raw_staging = new Sample[cnt]; + boost::scoped_array raw_staging(new Sample[cnt]); - if (read_unlocked (raw_staging, start, cnt) != cnt) { + if (read_unlocked (raw_staging.get(), start, cnt) != cnt) { error << _("cannot read sample data for unscaled peak computation") << endmsg; return -1; } @@ -367,7 +367,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t peaks[i].min = raw_staging[i]; } - delete [] raw_staging; return 0; } @@ -517,7 +516,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t framecnt_t i = 0; framecnt_t nvisual_peaks = 0; framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096); - raw_staging = new Sample[chunksize]; + boost::scoped_array raw_staging(new Sample[chunksize]); framepos_t frame_pos = start; double pixel_pos = floor (frame_pos / samples_per_visual_peak); @@ -542,14 +541,14 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t this loop early */ - memset (raw_staging, 0, sizeof (Sample) * chunksize); + memset (raw_staging.get(), 0, sizeof (Sample) * chunksize); } else { to_read = min (chunksize, (_length - current_frame)); - if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) { + if ((frames_read = read_unlocked (raw_staging.get(), current_frame, to_read)) == 0) { error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"), _name, to_read, current_frame, _length, strerror (errno)) << endmsg; @@ -587,7 +586,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t out: delete [] staging; - delete [] raw_staging; DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n"); From e5cc56a52303da563c98bae271ddcd9c07a5a22f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:42:34 -0400 Subject: [PATCH 37/69] Use boost::scoped_array for controlling scope of peak data in AudioSource::read_peaks --- libs/ardour/audiosource.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 720cb481be..f3b6926c00 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -324,7 +324,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t uint32_t nread; framecnt_t zero_fill = 0; int ret = -1; - PeakData* staging = 0; boost::scoped_ptr peakfile_descriptor(new FdFileDescriptor (peakpath, false, 0664)); int peakfile_fd = -1; @@ -419,7 +418,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t const framecnt_t chunksize = (framecnt_t) min (expected_peaks, 65536.0); - staging = new PeakData[chunksize]; + boost::scoped_array staging(new PeakData[chunksize]); /* compute the rounded up frame position */ @@ -440,7 +439,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) { error << string_compose(_("AudioSource: cannot open peakpath (b) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - delete [] staging; return 0; } @@ -456,7 +454,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t , sizeof (PeakData) * to_read, start_byte)); #ifndef WIN32 - if ((nread = ::pread (peakfile_fd, staging, sizeof (PeakData) * to_read, start_byte)) + if ((nread = ::pread (peakfile_fd, staging.get(), sizeof (PeakData) * to_read, start_byte)) != sizeof (PeakData) * to_read) { off_t fend = lseek (peakfile_fd, 0, SEEK_END); @@ -585,7 +583,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t } out: - delete [] staging; DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n"); From ebdf73a077013a6afa19ef5bf5ef84c0db39fe69 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:43:00 -0400 Subject: [PATCH 38/69] Remove use of goto in AudioSource::read_peaks --- libs/ardour/audiosource.cc | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index f3b6926c00..c9b80e7a5c 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -323,7 +323,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t int32_t to_read; uint32_t nread; framecnt_t zero_fill = 0; - int ret = -1; boost::scoped_ptr peakfile_descriptor(new FdFileDescriptor (peakpath, false, 0664)); int peakfile_fd = -1; @@ -461,7 +460,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t DEBUG_TRACE (DEBUG::Peaks, string_compose ("[%1]: cannot read peak data from peakfile (%2 peaks instead of %3) (%4) at start_byte = %5 _length = %6 versus len = %7 expected maxpeaks = %8 npeaks was %9" , _name, (nread / sizeof(PeakData)), to_read, g_strerror (errno), start_byte, _length, fend, ((_length - current_frame)/samples_per_file_peak), npeaks)); - goto out; + return -1; } #endif i = 0; @@ -494,8 +493,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); } - ret = 0; - } else { DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n"); @@ -550,7 +547,7 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"), _name, to_read, current_frame, _length, strerror (errno)) << endmsg; - goto out; + return -1; } } @@ -578,15 +575,10 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if (zero_fill) { memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); } - - ret = 0; } - out: - DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n"); - - return ret; + return 0; } int From 90c2a1c69db04fd98f301330afa4d9656053821f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:43:36 -0400 Subject: [PATCH 39/69] Use boost::scoped_array in AudioSource::build_peaks_from_scratch --- libs/ardour/audiosource.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index c9b80e7a5c..30c1852de3 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -584,8 +584,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t int AudioSource::build_peaks_from_scratch () { - Sample* buf = 0; - const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n"); @@ -605,20 +603,20 @@ AudioSource::build_peaks_from_scratch () framecnt_t cnt = _length; _peaks_built = false; - buf = new Sample[bufsize]; + boost::scoped_array buf(new Sample[bufsize]); while (cnt) { framecnt_t frames_to_read = min (bufsize, cnt); framecnt_t frames_read; - if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) { + if ((frames_read = read_unlocked (buf.get(), current_frame, frames_to_read)) != frames_to_read) { error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg; done_with_peakfile_writes (false); goto out; } - if (compute_and_write_peaks (buf, current_frame, frames_read, true, false, _FPP)) { + if (compute_and_write_peaks (buf.get(), current_frame, frames_read, true, false, _FPP)) { break; } @@ -643,8 +641,6 @@ AudioSource::build_peaks_from_scratch () unlink (peakpath.c_str()); } - delete [] buf; - return ret; } From 394f2b3ca71ca324fe89fab7c1caae1bd55a9143 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 13 Jul 2013 17:44:16 -0400 Subject: [PATCH 40/69] Use boost::scoped_array in AudioSource::compute_and_write_peaks --- libs/ardour/audiosource.cc | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 30c1852de3..35b7da2108 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -684,15 +684,13 @@ int AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt, bool force, bool intermediate_peaks_ready, framecnt_t fpp) { - Sample* buf2 = 0; framecnt_t to_do; uint32_t peaks_computed; - PeakData* peakbuf = 0; - int ret = -1; framepos_t current_frame; framecnt_t frames_done; const size_t blocksize = (128 * 1024); off_t first_peak_byte; + boost::scoped_array buf2; if (_peakfile_descriptor == 0) { prepare_for_peakfile_writes (); @@ -718,7 +716,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame #ifndef WIN32 if (::pwrite (_peakfile_fd, &x, sizeof (PeakData), byte) != sizeof (PeakData)) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; - goto out; + return -1; } #endif _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData))); @@ -744,19 +742,19 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame /* make a new contiguous buffer containing leftovers and the new stuff */ to_do = cnt + peak_leftover_cnt; - buf2 = new Sample[to_do]; + buf2.reset(new Sample[to_do]); /* the remnants */ - memcpy (buf2, peak_leftovers, peak_leftover_cnt * sizeof (Sample)); + memcpy (buf2.get(), peak_leftovers, peak_leftover_cnt * sizeof (Sample)); /* the new stuff */ - memcpy (buf2+peak_leftover_cnt, buf, cnt * sizeof (Sample)); + memcpy (buf2.get()+peak_leftover_cnt, buf, cnt * sizeof (Sample)); /* no more leftovers */ peak_leftover_cnt = 0; /* use the temporary buffer */ - buf = buf2; + buf = buf2.get(); /* make sure that when we write into the peakfile, we startup where we left off */ @@ -766,7 +764,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame to_do = cnt; } - peakbuf = new PeakData[(to_do/fpp)+1]; + boost::scoped_array peakbuf(new PeakData[(to_do/fpp)+1]); peaks_computed = 0; current_frame = first_frame; frames_done = 0; @@ -831,9 +829,9 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame } #ifndef WIN32 - if (::pwrite (_peakfile_fd, peakbuf, sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) { + if (::pwrite (_peakfile_fd, peakbuf.get(), sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; - goto out; + return -1; } #endif @@ -847,13 +845,7 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame } } - ret = 0; - - out: - delete [] peakbuf; - delete [] buf2; - - return ret; + return 0; } void From 2106a12edd6dcdf1189b7cfd68b07a0761d77c46 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 14 Jul 2013 11:34:31 +0200 Subject: [PATCH 41/69] improve caching of metric and tick patters * selectively clear cache (meterbridge, mixer) * free memory of patterns on clear --- gtk2_ardour/gain_meter.cc | 2 +- gtk2_ardour/meter_patterns.cc | 33 +++++++++++++++++++++++++++++---- gtk2_ardour/meter_patterns.h | 2 +- gtk2_ardour/meter_strip.cc | 2 -- gtk2_ardour/meterbridge.cc | 1 + 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index ae6f03f210..36ed5e918e 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -1086,7 +1086,7 @@ GainMeter::meter_configuration_changed (ChanCount c) set_meter_strip_name ("AudioMidiTrackMetricsInactive"); } } - meter_clear_pattern_cache(); // XXX only once + meter_clear_pattern_cache(4); } void diff --git a/gtk2_ardour/meter_patterns.cc b/gtk2_ardour/meter_patterns.cc index 9de01146b0..f749927e9a 100644 --- a/gtk2_ardour/meter_patterns.cc +++ b/gtk2_ardour/meter_patterns.cc @@ -485,9 +485,34 @@ gint meter_expose_metrics (GdkEventExpose *ev, std::vector typ return true; } -void meter_clear_pattern_cache() { - // TODO allow to clear meterbridge "*Left|Right" patterns independenly - metric_patterns.clear(); - ticks_patterns.clear(); +void meter_clear_pattern_cache(int which) { + MetricPatterns::iterator i = metric_patterns.begin(); + TickPatterns::iterator j = ticks_patterns.begin(); + + while (i != metric_patterns.end()) { + int m = 4; + std::string n = i->first; + if (n.substr(n.length() - 4) == "Left") { m = 1; } + if (n.substr(n.length() - 5) == "Right") { m = 2; } + if (which & m) { + cairo_pattern_destroy(i->second); + metric_patterns.erase(i++); + } else { + ++i; + } + } + + while (j != ticks_patterns.end()) { + int m = 4; + std::string n = j->first; + if (n.substr(n.length() - 4) == "Left") { m = 1; } + if (n.substr(n.length() - 5) == "Right") { m = 2; } + if (which & m) { + cairo_pattern_destroy(j->second); + ticks_patterns.erase(j++); + } else { + ++j; + } + } RedrawMetrics(); } diff --git a/gtk2_ardour/meter_patterns.h b/gtk2_ardour/meter_patterns.h index df755f7ace..a664f478f2 100644 --- a/gtk2_ardour/meter_patterns.h +++ b/gtk2_ardour/meter_patterns.h @@ -40,7 +40,7 @@ cairo_pattern_t* meter_render_metrics (Gtk::Widget& w, std::vector types, Gtk::DrawingArea *mta); gint meter_expose_metrics (GdkEventExpose *ev, std::vector types, Gtk::DrawingArea *mma); -void meter_clear_pattern_cache(); +void meter_clear_pattern_cache(int which=7); #endif diff --git a/gtk2_ardour/meter_strip.cc b/gtk2_ardour/meter_strip.cc index a4cc56d61c..88a946585a 100644 --- a/gtk2_ardour/meter_strip.cc +++ b/gtk2_ardour/meter_strip.cc @@ -372,14 +372,12 @@ MeterStrip::meter_configuration_changed (ChanCount c) void MeterStrip::on_size_request (Gtk::Requisition* r) { - meter_clear_pattern_cache(); VBox::on_size_request(r); } void MeterStrip::on_size_allocate (Gtk::Allocation& a) { - meter_clear_pattern_cache(); const int wh = a.get_height(); int nh = ceilf(wh * .11f); if (nh < 52) nh = 52; diff --git a/gtk2_ardour/meterbridge.cc b/gtk2_ardour/meterbridge.cc index 227f533a18..24b21656d1 100644 --- a/gtk2_ardour/meterbridge.cc +++ b/gtk2_ardour/meterbridge.cc @@ -327,6 +327,7 @@ Meterbridge::scroll_right () void Meterbridge::on_size_request (Gtk::Requisition* r) { + meter_clear_pattern_cache(3); Gtk::Window::on_size_request(r); Gdk::Geometry geom; From 13a0f14db71dd22b9a6c7f7039ebf6089144a7f8 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 07:52:37 -0400 Subject: [PATCH 42/69] Use ::read instead of pread in AudioSource::read_peaks for portability This destroys the atomicity of pread() and thus suggests that we should do something else to ensure that multithread access to peakfiles (if it does in fact exist) is safe. OTOH, there may be no such thing, since they are designed for the GUI, which is single threaded (for now) --- libs/ardour/audiosource.cc | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 35b7da2108..776749fb57 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -370,8 +370,9 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t if (scale == 1.0) { + off_t offset = 0; off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData); - + ssize_t bytes_to_read = sizeof (PeakData)* npeaks; /* open, read, close */ if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) { @@ -381,11 +382,16 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n"); -#ifndef WIN32 - nread = ::pread (peakfile_fd, peaks, sizeof (PeakData)* npeaks, first_peak_byte); -#endif + offset = lseek (peakfile_fd, first_peak_byte, SEEK_SET); - if (nread != sizeof (PeakData) * npeaks) { + if (offset != first_peak_byte) { + error << string_compose(_("AudioSource: could not seek to correct location in peak file \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; + return -1; + } + + nread = ::read (peakfile_fd, peaks, bytes_to_read); + + if (nread != bytes_to_read) { DEBUG_TRACE (DEBUG::Peaks, string_compose ("[%1]: Cannot read peaks from peakfile! (read only %2 not %3 at sample %4 = byte %5 )\n" , _name, nread, npeaks, start, first_peak_byte)); return -1; @@ -448,13 +454,20 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t uint32_t start_byte = current_stored_peak * sizeof(PeakData); tnp = min ((framecnt_t)(_length/samples_per_file_peak - current_stored_peak), (framecnt_t) expected_peaks); to_read = min (chunksize, tnp); + ssize_t bytes_to_read = sizeof (PeakData) * to_read; DEBUG_TRACE (DEBUG::Peaks, string_compose ("reading %1 bytes from peakfile @ %2\n" - , sizeof (PeakData) * to_read, start_byte)); + , bytes_to_read, start_byte)); -#ifndef WIN32 - if ((nread = ::pread (peakfile_fd, staging.get(), sizeof (PeakData) * to_read, start_byte)) - != sizeof (PeakData) * to_read) { + + off_t offset = lseek (peakfile_fd, start_byte, SEEK_SET); + + if (offset != start_byte) { + error << string_compose(_("AudioSource: could not seek to correct location in peak file \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; + return -1; + } + + if ((nread = ::read (peakfile_fd, staging.get(), bytes_to_read)) != bytes_to_read) { off_t fend = lseek (peakfile_fd, 0, SEEK_END); @@ -462,7 +475,6 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t , _name, (nread / sizeof(PeakData)), to_read, g_strerror (errno), start_byte, _length, fend, ((_length - current_frame)/samples_per_file_peak), npeaks)); return -1; } -#endif i = 0; stored_peaks_read = nread / sizeof(PeakData); } From db3edc40184b8235df92fe44df066944bbd130aa Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 07:53:45 -0400 Subject: [PATCH 43/69] Use ::write instead of pwrite in AudioSource::compute_and_write_peaks for portability This destroys the atomicity of pwrite() and thus suggests that we should do something else to ensure that multithread access to peakfiles (if it does in fact exist) is safe. OTOH, there may be no such thing, since they are designed for the GUI, which is single threaded (for now) --- libs/ardour/audiosource.cc | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 776749fb57..ff92b8977d 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -725,12 +725,18 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData); -#ifndef WIN32 - if (::pwrite (_peakfile_fd, &x, sizeof (PeakData), byte) != sizeof (PeakData)) { + off_t offset = lseek (_peakfile_fd, byte, SEEK_SET); + + if (offset != byte) { + error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg; + return -1; + } + + if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; return -1; } -#endif + _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData))); { @@ -840,14 +846,24 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame } } -#ifndef WIN32 - if (::pwrite (_peakfile_fd, peakbuf.get(), sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) { + + off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET); + + if (offset != first_peak_byte) { + error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg; + return -1; + } + + ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed; + + ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write); + + if (bytes_written != bytes_to_write) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; return -1; } -#endif - _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed)); + _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write)); if (frames_done) { Glib::Threads::Mutex::Lock lm (_peaks_ready_lock); From 5131b8300f26a9af790936389203fa94667aee67 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 07:54:29 -0400 Subject: [PATCH 44/69] Use g_open instead of ::open in PBD::FileManager g_open is a macro that evaluates to ::open on linux(and mac) so this is only a change for windows. --- libs/pbd/file_manager.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/pbd/file_manager.cc b/libs/pbd/file_manager.cc index e02bcc2b0d..0c79011af1 100644 --- a/libs/pbd/file_manager.cc +++ b/libs/pbd/file_manager.cc @@ -24,6 +24,9 @@ #include #include +#include +#include + #ifdef __APPLE__ #include #endif @@ -226,7 +229,7 @@ FdFileDescriptor::open () { /* we must have a lock on the FileManager's mutex */ - _fd = ::open (_path.c_str(), _writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode); + _fd = ::g_open (_path.c_str(), _writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode); return (_fd == -1); } From 542c4b024e8e06d4e4b55ae6dcf20c0bc4c5344d Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 07:55:01 -0400 Subject: [PATCH 45/69] Don't use errno after g_file_test on windows --- libs/ardour/file_source.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index 0921498186..06d4fb6175 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -496,13 +496,14 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex goto out; } +#ifndef WIN32 if (errno != ENOENT) { error << string_compose( _("Filesource: cannot check for existing file (%1): %2"), path, strerror (errno)) << endmsg; goto out; } - +#endif /* a new file */ isnew = true; ret = true; From f08d9591e6e16d81d71b8b81ff3c99d7f58c1f01 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 07:55:36 -0400 Subject: [PATCH 46/69] Fix reading and writing of files on windows in PBD::FileManager --- libs/pbd/file_manager.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libs/pbd/file_manager.cc b/libs/pbd/file_manager.cc index 0c79011af1..2cfa63ae39 100644 --- a/libs/pbd/file_manager.cc +++ b/libs/pbd/file_manager.cc @@ -228,8 +228,19 @@ bool FdFileDescriptor::open () { /* we must have a lock on the FileManager's mutex */ - - _fd = ::g_open (_path.c_str(), _writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode); + + /* files must be opened with O_BINARY flag on windows + * or it treats the file as a text stream and puts in + * line endings in etc + */ +#ifdef WIN32 +#define WRITE_FLAGS O_RDWR | O_CREAT | O_BINARY +#define READ_FLAGS O_RDONLY | O_BINARY +#else +#define WRITE_FLAGS O_RDWR | O_CREAT +#define READ_FLAGS O_RDONLY +#endif + _fd = ::g_open (_path.c_str(), _writeable ? WRITE_FLAGS : READ_FLAGS, _mode); return (_fd == -1); } From 43f7813b248686bfa89600f91dccd83017dfe669 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 08:05:37 -0400 Subject: [PATCH 47/69] Fix portability of Session::source_search_path --- gtk2_ardour/ardour_ui.cc | 4 +- gtk2_ardour/ardour_ui.h | 2 +- gtk2_ardour/missing_file_dialog.cc | 17 ++++++-- libs/ardour/ardour/file_source.h | 2 +- libs/ardour/ardour/session.h | 2 +- libs/ardour/file_source.cc | 31 +++++--------- libs/ardour/session.cc | 69 +++++++++++------------------- 7 files changed, 53 insertions(+), 74 deletions(-) diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index e3655a0d7a..91dbd999df 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -288,7 +288,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) /* and ambiguous files */ - ARDOUR::FileSource::AmbiguousFileName.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::ambiguous_file, this, _1, _2, _3)); + ARDOUR::FileSource::AmbiguousFileName.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::ambiguous_file, this, _1, _2)); /* lets get this party started */ @@ -4050,7 +4050,7 @@ ARDOUR_UI::missing_file (Session*s, std::string str, DataType type) } int -ARDOUR_UI::ambiguous_file (std::string file, std::string /*path*/, std::vector hits) +ARDOUR_UI::ambiguous_file (std::string file, std::vector hits) { AmbiguousFileDialog dialog (file, hits); diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 5817293b29..7a8a0193f1 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -713,7 +713,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr void fontconfig_dialog (); int missing_file (ARDOUR::Session*s, std::string str, ARDOUR::DataType type); - int ambiguous_file (std::string file, std::string path, std::vector hits); + int ambiguous_file (std::string file, std::vector hits); bool click_button_clicked (GdkEventButton *); diff --git a/gtk2_ardour/missing_file_dialog.cc b/gtk2_ardour/missing_file_dialog.cc index c7cb7f5edc..b1e2081a1d 100644 --- a/gtk2_ardour/missing_file_dialog.cc +++ b/gtk2_ardour/missing_file_dialog.cc @@ -19,12 +19,17 @@ #include "pbd/compose.h" #include "pbd/replace_all.h" #include "pbd/strsplit.h" +#include "pbd/search_path.h" #include "ardour/session.h" #include "missing_file_dialog.h" #include "i18n.h" +#ifdef SearchPath +#undef SearchPath +#endif + using namespace Gtk; using namespace std; using namespace ARDOUR; @@ -56,14 +61,18 @@ MissingFileDialog::MissingFileDialog (Session* s, const std::string& path, DataT break; } - string dirstr; + vector source_dirs = s->source_search_path (type); + vector::iterator i = source_dirs.begin(); + ostringstream oss; + oss << *i << endl; - dirstr = s->source_search_path (type); - replace_all (dirstr, ":", "\n"); + while (++i != source_dirs.end()) { + oss << *i << endl; + } msg.set_justify (JUSTIFY_CENTER); msg.set_markup (string_compose (_("%1 cannot find the %2 file\n\n%3\n\nin any of these folders:\n\n\ -%4\n\n"), PROGRAM_NAME, typestr, Glib::Markup::escape_text(path), Glib::Markup::escape_text (dirstr))); +%4\n\n"), PROGRAM_NAME, typestr, Glib::Markup::escape_text(path), Glib::Markup::escape_text (oss.str()))); HBox* hbox = manage (new HBox); hbox->pack_start (msg, false, true); diff --git a/libs/ardour/ardour/file_source.h b/libs/ardour/ardour/file_source.h index 5898d04f0a..52dca18feb 100644 --- a/libs/ardour/ardour/file_source.h +++ b/libs/ardour/ardour/file_source.h @@ -79,7 +79,7 @@ public: virtual void set_path (const std::string&); - static PBD::Signal3 > AmbiguousFileName; + static PBD::Signal2 > AmbiguousFileName; protected: FileSource (Session& session, DataType type, diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index a149224607..85866f99a5 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -820,7 +820,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void request_resume_timecode_transmission (); bool timecode_transmission_suspended () const; - std::string source_search_path(DataType) const; + std::vector source_search_path(DataType) const; void ensure_search_path_includes (const std::string& path, DataType type); std::list unknown_processors () const; diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index 06d4fb6175..c7b03cbdb7 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -51,7 +51,7 @@ using namespace ARDOUR; using namespace PBD; using namespace Glib; -PBD::Signal3 > FileSource::AmbiguousFileName; +PBD::Signal2 > FileSource::AmbiguousFileName; FileSource::FileSource (Session& session, DataType type, const string& path, const string& origin, Source::Flag flag) : Source(session, type, path, flag) @@ -240,19 +240,15 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist isnew = false; if (!Glib::path_is_absolute (path)) { - vector dirs; vector hits; string fullpath; + std::vector dirs = s.source_search_path (type); - string search_path = s.source_search_path (type); - - if (search_path.length() == 0) { + if (dirs.size() == 0) { error << _("FileSource: search path not set") << endmsg; goto out; } - split (search_path, dirs, ':'); - hits.clear (); for (vector::iterator i = dirs.begin(); i != dirs.end(); ++i) { @@ -296,7 +292,7 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist /* more than one match: ask the user */ - int which = FileSource::AmbiguousFileName (path, search_path, de_duped_hits).get_value_or (-1); + int which = FileSource::AmbiguousFileName (path, de_duped_hits).get_value_or (-1); if (which < 0) { goto out; @@ -310,8 +306,7 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist if (must_exist) { error << string_compose( - _("Filesource: cannot find required file (%1): while searching %2"), - path, search_path) << endmsg; + _("Filesource: cannot find required file (%1)"), path) << endmsg; goto out; } else { isnew = true; @@ -357,8 +352,6 @@ bool FileSource::find_2X (Session& s, DataType type, const string& path, bool must_exist, bool& isnew, uint16_t& chan, string& found_path) { - string search_path = s.source_search_path (type); - string pathstr = path; string::size_type pos; bool ret = false; @@ -369,18 +362,17 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex /* non-absolute pathname: find pathstr in search path */ - vector dirs; + vector dirs = s.source_search_path (type); + int cnt; string fullpath; string keeppath; - if (search_path.length() == 0) { + if (dirs.size() == 0) { error << _("FileSource: search path not set") << endmsg; goto out; } - split (search_path, dirs, ':'); - cnt = 0; for (vector::iterator i = dirs.begin(); i != dirs.end(); ++i) { @@ -437,16 +429,15 @@ FileSource::find_2X (Session& s, DataType type, const string& path, bool must_ex if (cnt > 1) { error << string_compose ( - _("FileSource: \"%1\" is ambigous when searching %2\n\t"), - pathstr, search_path) << endmsg; + _("FileSource: \"%1\" is ambigous when searching\n\t"), pathstr) << endmsg; goto out; } else if (cnt == 0) { if (must_exist) { error << string_compose( - _("Filesource: cannot find required file (%1): while searching %2"), - pathstr, search_path) << endmsg; + _("Filesource: cannot find required file (%1): while searching") + , pathstr) << endmsg; goto out; } else { isnew = true; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 914c6a9a77..476682158f 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -44,8 +44,8 @@ #include "pbd/stacktrace.h" #include "pbd/file_utils.h" #include "pbd/convert.h" -#include "pbd/strsplit.h" #include "pbd/unwind.h" +#include "pbd/search_path.h" #include "ardour/amp.h" #include "ardour/analyser.h" @@ -94,6 +94,10 @@ #include "i18n.h" +#ifdef SearchPath +#undef SearchPath +#endif + namespace ARDOUR { class MidiSource; class Processor; @@ -4420,18 +4424,18 @@ Session::end_time_changed (framepos_t old) } } -string +std::vector Session::source_search_path (DataType type) const { - vector s; + SearchPath sp; if (session_dirs.size() == 1) { switch (type) { case DataType::AUDIO: - s.push_back (_session_dir->sound_path()); + sp.push_back (_session_dir->sound_path()); break; case DataType::MIDI: - s.push_back (_session_dir->midi_path()); + sp.push_back (_session_dir->midi_path()); break; } } else { @@ -4439,10 +4443,10 @@ Session::source_search_path (DataType type) const SessionDirectory sdir (i->path); switch (type) { case DataType::AUDIO: - s.push_back (sdir.sound_path()); + sp.push_back (sdir.sound_path()); break; case DataType::MIDI: - s.push_back (sdir.midi_path()); + sp.push_back (sdir.midi_path()); break; } } @@ -4451,49 +4455,30 @@ Session::source_search_path (DataType type) const if (type == DataType::AUDIO) { const string sound_path_2X = _session_dir->sound_path_2X(); if (Glib::file_test (sound_path_2X, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) { - if (find (s.begin(), s.end(), sound_path_2X) == s.end()) { - s.push_back (sound_path_2X); + if (find (sp.begin(), sp.end(), sound_path_2X) == sp.end()) { + sp.push_back (sound_path_2X); } } } - /* now check the explicit (possibly user-specified) search path - */ - - vector dirs; + // now check the explicit (possibly user-specified) search path switch (type) { case DataType::AUDIO: - split (config.get_audio_search_path (), dirs, ':'); + sp += SearchPath(config.get_audio_search_path ()); break; case DataType::MIDI: - split (config.get_midi_search_path (), dirs, ':'); + sp += SearchPath(config.get_midi_search_path ()); break; } - for (vector::iterator i = dirs.begin(); i != dirs.end(); ++i) { - if (find (s.begin(), s.end(), *i) == s.end()) { - s.push_back (*i); - } - } - - string search_path; - - for (vector::iterator si = s.begin(); si != s.end(); ++si) { - if (!search_path.empty()) { - search_path += ':'; - } - search_path += *si; - } - - return search_path; + return sp; } void Session::ensure_search_path_includes (const string& path, DataType type) { - string search_path; - vector dirs; + SearchPath sp; if (path == ".") { return; @@ -4501,16 +4486,14 @@ Session::ensure_search_path_includes (const string& path, DataType type) switch (type) { case DataType::AUDIO: - search_path = config.get_audio_search_path (); + sp += SearchPath(config.get_audio_search_path ()); break; case DataType::MIDI: - search_path = config.get_midi_search_path (); + sp += SearchPath (config.get_midi_search_path ()); break; } - split (search_path, dirs, ':'); - - for (vector::iterator i = dirs.begin(); i != dirs.end(); ++i) { + for (vector::iterator i = sp.begin(); i != sp.end(); ++i) { /* No need to add this new directory if it has the same inode as an existing one; checking inode rather than name prevents duplicated directories when we are using symlinks. @@ -4522,18 +4505,14 @@ Session::ensure_search_path_includes (const string& path, DataType type) } } - if (!search_path.empty()) { - search_path += ':'; - } - - search_path += path; + sp += path; switch (type) { case DataType::AUDIO: - config.set_audio_search_path (search_path); + config.set_audio_search_path (sp.to_string()); break; case DataType::MIDI: - config.set_midi_search_path (search_path); + config.set_midi_search_path (sp.to_string()); break; } } From c00e03cced06703acdf32331c92b9f533d9c3ece Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 08:06:09 -0400 Subject: [PATCH 48/69] Don't include jack/weakjack.h header when compiling for windows --- libs/ardour/ardour/audioengine.h | 3 +++ libs/ardour/audioengine.cc | 2 -- libs/ardour/port.cc | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 363238baad..10400c41d7 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -37,7 +37,10 @@ #include "pbd/signals.h" #include "pbd/stacktrace.h" +#ifndef WIN32 #include +#endif + #include #include #include diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 690012e529..a69e98283e 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -31,8 +31,6 @@ #include "pbd/unknown_type.h" #include "pbd/epa.h" -#include - #include "midi++/port.h" #include "midi++/jack_midi_port.h" #include "midi++/mmc.h" diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index 3473b73617..a1eacca96e 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -21,7 +21,9 @@ #include "libardour-config.h" #endif +#ifndef WIN32 #include // so that we can test for new functions at runtime +#endif #include "pbd/compose.h" #include "pbd/error.h" From 49edb904849af2e4519a2b7a670bd9834bb753ab Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 08:06:39 -0400 Subject: [PATCH 49/69] Add ladspa directory name to directory names --- libs/ardour/ardour/directory_names.h | 1 + libs/ardour/directory_names.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/libs/ardour/ardour/directory_names.h b/libs/ardour/ardour/directory_names.h index 9f7c778d33..cb4701d336 100644 --- a/libs/ardour/ardour/directory_names.h +++ b/libs/ardour/ardour/directory_names.h @@ -36,6 +36,7 @@ extern const char* const export_formats_dir_name; extern const char* const templates_dir_name; extern const char* const route_templates_dir_name; extern const char* const surfaces_dir_name; +extern const char* const ladspa_dir_name; extern const char* const user_config_dir_name; extern const char* const panner_dir_name; diff --git a/libs/ardour/directory_names.cc b/libs/ardour/directory_names.cc index 0632c6f8f2..6fb15eaabd 100644 --- a/libs/ardour/directory_names.cc +++ b/libs/ardour/directory_names.cc @@ -36,6 +36,7 @@ const char* const export_formats_dir_name = X_("export"); const char* const templates_dir_name = X_("templates"); const char* const route_templates_dir_name = X_("route_templates"); const char* const surfaces_dir_name = X_("surfaces"); +const char* const ladspa_dir_name = X_("ladspa"); const char* const panner_dir_name = X_("panners"); /* these should end up using variants of PROGRAM_NAME */ From 2c7a1179c627a35a47665c807ae82162bb838a9c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 08:07:12 -0400 Subject: [PATCH 50/69] Fix finding panner modules on windows by looking for files with *.dll extension --- libs/ardour/panner_manager.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/ardour/panner_manager.cc b/libs/ardour/panner_manager.cc index 06fc42aab9..4e4ad7fe4d 100644 --- a/libs/ardour/panner_manager.cc +++ b/libs/ardour/panner_manager.cc @@ -71,6 +71,7 @@ PannerManager::discover_panners () Glib::PatternSpec so_extension_pattern("*.so"); Glib::PatternSpec dylib_extension_pattern("*.dylib"); + Glib::PatternSpec dll_extension_pattern("*.dll"); find_matching_files_in_search_path (panner_search_path (), so_extension_pattern, panner_modules); @@ -78,6 +79,9 @@ PannerManager::discover_panners () find_matching_files_in_search_path (panner_search_path (), dylib_extension_pattern, panner_modules); + find_matching_files_in_search_path (panner_search_path (), + dll_extension_pattern, panner_modules); + DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for panners in %1"), panner_search_path().to_string())); for (vector::iterator i = panner_modules.begin(); i != panner_modules.end(); ++i) { From 5bc4e54b7da3eb139d699c6e371d43540c69b519 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 08:08:09 -0400 Subject: [PATCH 51/69] Add ARDOUR::ladspa_search_path function to get LADSPA module directories --- libs/ardour/ardour/ladspa_search_path.h | 39 ++++++++++++++++++ libs/ardour/ladspa_search_path.cc | 55 +++++++++++++++++++++++++ libs/ardour/wscript | 1 + 3 files changed, 95 insertions(+) create mode 100644 libs/ardour/ardour/ladspa_search_path.h create mode 100644 libs/ardour/ladspa_search_path.cc diff --git a/libs/ardour/ardour/ladspa_search_path.h b/libs/ardour/ardour/ladspa_search_path.h new file mode 100644 index 0000000000..791bba9188 --- /dev/null +++ b/libs/ardour/ardour/ladspa_search_path.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2011 Tim Mayberry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef ARDOUR_LADSPA_SEARCH_PATH_INCLUDED +#define ARDOUR_LADSPA_SEARCH_PATH_INCLUDED + +#include "pbd/search_path.h" + +namespace ARDOUR { + + /** + * return a SearchPath containing directories in which to look for + * LADSPA plugins. + * + * If LADSPA_PATH is defined then the SearchPath returned + * will contain the directories specified in it as well as the + * user and system directories. + */ + PBD::SearchPath ladspa_search_path (); + +} // namespace ARDOUR + +#endif diff --git a/libs/ardour/ladspa_search_path.cc b/libs/ardour/ladspa_search_path.cc new file mode 100644 index 0000000000..7b675d081d --- /dev/null +++ b/libs/ardour/ladspa_search_path.cc @@ -0,0 +1,55 @@ +/* + Copyright (C) 2011 Tim Mayberry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +#include "ardour/ladspa_search_path.h" +#include "ardour/directory_names.h" +#include "ardour/filesystem_paths.h" + +namespace { + const char * const ladspa_env_variable_name = "LADSPA_PATH"; +} // anonymous + +using namespace PBD; + +namespace ARDOUR { + +SearchPath +ladspa_search_path () +{ + SearchPath spath_env (Glib::getenv(ladspa_env_variable_name)); + + SearchPath spath (user_config_directory ()); + + spath += ardour_dll_directory (); + spath.add_subdirectory_to_paths (ladspa_dir_name); + +#ifndef WIN32 + spath.push_back ("/usr/local/lib64/ladspa"); + spath.push_back ("/usr/local/lib/ladspa"); + spath.push_back ("/usr/lib64/ladspa"); + spath.push_back ("/usr/lib/ladspa"); + spath.push_back ("/Library/Audio/Plug-Ins/LADSPA"); +#endif + + return spath_env + spath; +} + +} // namespace ARDOUR diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 4e7e23aa1a..94f2445859 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -101,6 +101,7 @@ libardour_sources = [ 'jack_slave.cc', 'kmeterdsp.cc', 'ladspa_plugin.cc', + 'ladspa_search_path.cc', 'location.cc', 'location_importer.cc', 'ltc_slave.cc', From 83e05ec0ec236f4dc327935377206966836027eb Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 12:38:03 -0400 Subject: [PATCH 52/69] Use ARDOUR::ladspa_search_path and PBD::find_matching_files to find LADSPA modules --- libs/ardour/ardour/plugin_manager.h | 3 - libs/ardour/ladspa_search_path.cc | 6 ++ libs/ardour/plugin_manager.cc | 113 +++++++++------------------- 3 files changed, 42 insertions(+), 80 deletions(-) diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h index a7a5703690..2464368ae7 100644 --- a/libs/ardour/ardour/plugin_manager.h +++ b/libs/ardour/ardour/plugin_manager.h @@ -51,7 +51,6 @@ class PluginManager : public boost::noncopyable { void refresh (); - int add_ladspa_directory (std::string dirpath); int add_windows_vst_directory (std::string dirpath); int add_lxvst_directory (std::string dirpath); @@ -103,7 +102,6 @@ class PluginManager : public boost::noncopyable { std::map rdf_type; - std::string ladspa_path; std::string windows_vst_path; std::string lxvst_path; @@ -127,7 +125,6 @@ class PluginManager : public boost::noncopyable { int lxvst_discover_from_path (std::string path); int lxvst_discover (std::string path); - int ladspa_discover_from_path (std::string path); int ladspa_discover (std::string path); std::string get_ladspa_category (uint32_t id); diff --git a/libs/ardour/ladspa_search_path.cc b/libs/ardour/ladspa_search_path.cc index 7b675d081d..6ecc1557a3 100644 --- a/libs/ardour/ladspa_search_path.cc +++ b/libs/ardour/ladspa_search_path.cc @@ -19,6 +19,8 @@ #include +#include "pbd/pathexpand.h" + #include "ardour/ladspa_search_path.h" #include "ardour/directory_names.h" #include "ardour/filesystem_paths.h" @@ -46,6 +48,10 @@ ladspa_search_path () spath.push_back ("/usr/local/lib/ladspa"); spath.push_back ("/usr/lib64/ladspa"); spath.push_back ("/usr/lib/ladspa"); +#endif + +#ifdef __APPLE__ + spath.push_back (expand_path ("~/Library/Audio/Plug-Ins/LADSPA")); spath.push_back ("/Library/Audio/Plug-Ins/LADSPA"); #endif diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index 6ea0292872..8d4e625876 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -45,9 +45,11 @@ #endif //LXVST_SUPPORT #include +#include #include "pbd/pathscanner.h" #include "pbd/whitespace.h" +#include "pbd/file_utils.h" #include "ardour/debug.h" #include "ardour/filesystem_paths.h" @@ -57,6 +59,12 @@ #include "ardour/plugin_manager.h" #include "ardour/rc_configuration.h" +#ifdef SearchPath +#undef SearchPath +#endif + +#include "ardour/ladspa_search_path.h" + #ifdef LV2_SUPPORT #include "ardour/lv2_plugin.h" #endif @@ -79,6 +87,8 @@ #include "i18n.h" +#include "ardour/debug.h" + using namespace ARDOUR; using namespace PBD; using namespace std; @@ -128,10 +138,6 @@ PluginManager::PluginManager () } #endif /* Native LinuxVST support*/ - if ((s = getenv ("LADSPA_PATH"))) { - ladspa_path = s; - } - if ((s = getenv ("VST_PATH"))) { windows_vst_path = s; } else if ((s = getenv ("VST_PLUGINS"))) { @@ -200,91 +206,38 @@ PluginManager::refresh () void PluginManager::ladspa_refresh () { - if (_ladspa_plugin_info) + if (_ladspa_plugin_info) { _ladspa_plugin_info->clear (); - else + } else { _ladspa_plugin_info = new ARDOUR::PluginInfoList (); - - static const char *standard_paths[] = { - "/usr/local/lib64/ladspa", - "/usr/local/lib/ladspa", - "/usr/lib64/ladspa", - "/usr/lib/ladspa", - "/Library/Audio/Plug-Ins/LADSPA", - "" - }; + } /* allow LADSPA_PATH to augment, not override standard locations */ /* Only add standard locations to ladspa_path if it doesn't * already contain them. Check for trailing G_DIR_SEPARATOR too. */ + + vector ladspa_modules; - int i; - for (i = 0; standard_paths[i][0]; i++) { - size_t found = ladspa_path.find(standard_paths[i]); - if (found != ladspa_path.npos) { - switch (ladspa_path[found + strlen(standard_paths[i])]) { - case ':' : - case '\0': - continue; - case G_DIR_SEPARATOR : - if (ladspa_path[found + strlen(standard_paths[i]) + 1] == ':' || - ladspa_path[found + strlen(standard_paths[i]) + 1] == '\0') { - continue; - } - } - } - if (!ladspa_path.empty()) - ladspa_path += ":"; + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string())); - ladspa_path += standard_paths[i]; + Glib::PatternSpec so_extension_pattern("*.so"); + Glib::PatternSpec dylib_extension_pattern("*.dylib"); + Glib::PatternSpec dll_extension_pattern("*.dll"); + find_matching_files_in_search_path (ladspa_search_path (), + so_extension_pattern, ladspa_modules); + + find_matching_files_in_search_path (ladspa_search_path (), + dylib_extension_pattern, ladspa_modules); + + find_matching_files_in_search_path (ladspa_search_path (), + dll_extension_pattern, ladspa_modules); + + for (vector::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) { + ladspa_discover (*i); } - - DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_path)); - - ladspa_discover_from_path (ladspa_path); -} - - -int -PluginManager::add_ladspa_directory (string path) -{ - if (ladspa_discover_from_path (path) == 0) { - ladspa_path += ':'; - ladspa_path += path; - return 0; - } - return -1; -} - -static bool ladspa_filter (const string& str, void */*arg*/) -{ - /* Not a dotfile, has a prefix before a period, suffix is "so" */ - - return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3)); -} - -int -PluginManager::ladspa_discover_from_path (string /*path*/) -{ - PathScanner scanner; - vector *plugin_objects; - vector::iterator x; - int ret = 0; - - plugin_objects = scanner (ladspa_path, ladspa_filter, 0, false, true); - - if (plugin_objects) { - for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) { - ladspa_discover (**x); - } - - vector_delete (plugin_objects); - } - - return ret; } static bool rdf_filter (const string &str, void* /*arg*/) @@ -370,6 +323,8 @@ PluginManager::add_lrdf_data (const string &path) int PluginManager::ladspa_discover (string path) { + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path)); + Glib::Module module(path); const LADSPA_Descriptor *descriptor; LADSPA_Descriptor_Function dfunc; @@ -390,6 +345,8 @@ PluginManager::ladspa_discover (string path) dfunc = (LADSPA_Descriptor_Function)func; + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path)); + for (uint32_t i = 0; ; ++i) { if ((descriptor = dfunc (i)) == 0) { break; @@ -443,6 +400,8 @@ PluginManager::ladspa_discover (string path) if(!found){ _ladspa_plugin_info->push_back (info); } + + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs)); } // GDB WILL NOT LIKE YOU IF YOU DO THIS From 81dbc20bacfe1566065ada3cf49ec98939a609b1 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 12:40:06 -0400 Subject: [PATCH 53/69] Add basic test for PluginManager and LADSPA plugins --- libs/ardour/test/plugins_test.cc | 54 ++++++++++++++++++++++++++++++++ libs/ardour/test/plugins_test.h | 12 +++++++ libs/ardour/wscript | 2 ++ 3 files changed, 68 insertions(+) create mode 100644 libs/ardour/test/plugins_test.cc create mode 100644 libs/ardour/test/plugins_test.h diff --git a/libs/ardour/test/plugins_test.cc b/libs/ardour/test/plugins_test.cc new file mode 100644 index 0000000000..362a56df7f --- /dev/null +++ b/libs/ardour/test/plugins_test.cc @@ -0,0 +1,54 @@ +#include + +#include "ardour/plugin_manager.h" +#include "ardour/ladspa_search_path.h" + +#include "plugins_test.h" +#include "test_common.h" + +CPPUNIT_TEST_SUITE_REGISTRATION (PluginsTest); + +using namespace std; +using namespace ARDOUR; +using namespace PBD; + +void +print_plugin_info (PluginInfoPtr pp) +{ + cout << "LADSPA Plugin, name " << pp->name + << ", category " << pp->category + << ", creator " << pp->creator + << ", path " << pp->path + << ", n_inputs " << pp->n_inputs.n_audio () + << ", n_outputs " << pp->n_outputs.n_audio () + << endl; + +} + +void +PluginsTest::test () +{ + PluginManager& pm = PluginManager::instance (); + + pm.refresh (); + + SearchPath ladspa_paths(ladspa_search_path ()); + + cout << "Number of Ladspa paths found: " << ladspa_paths.size () << endl; + + for (vector::iterator i = ladspa_paths.begin (); i != ladspa_paths.end(); ++i) + { + cout << "LADSPA search path includes: " << *i << endl; + } + + PluginInfoList& ladspa_list = pm.ladspa_plugin_info (); + + cout << "Number of Ladspa plugins found: " << ladspa_list.size () << endl; + + for (PluginInfoList::iterator i = ladspa_list.begin (); i != ladspa_list.end(); ++i) + { + print_plugin_info (*i); + } + + +} diff --git a/libs/ardour/test/plugins_test.h b/libs/ardour/test/plugins_test.h new file mode 100644 index 0000000000..1503b2bde2 --- /dev/null +++ b/libs/ardour/test/plugins_test.h @@ -0,0 +1,12 @@ +#include +#include + +class PluginsTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE (PluginsTest); + CPPUNIT_TEST (test); + CPPUNIT_TEST_SUITE_END (); + +public: + void test (); +}; diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 94f2445859..256ff1c6c0 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -481,6 +481,7 @@ def build(bld): create_ardour_test_program(bld, obj.includes, 'framepos_minus_beats', 'test_framepos_minus_beats', ['test/framepos_minus_beats_test.cc']) create_ardour_test_program(bld, obj.includes, 'playlist_equivalent_regions', 'test_playlist_equivalent_regions', ['test/playlist_equivalent_regions_test.cc']) create_ardour_test_program(bld, obj.includes, 'playlist_layering', 'test_playlist_layering', ['test/playlist_layering_test.cc']) + create_ardour_test_program(bld, obj.includes, 'plugins_test', 'test_plugins', ['test/plugins_test.cc']) create_ardour_test_program(bld, obj.includes, 'region_naming', 'test_region_naming', ['test/region_naming_test.cc']) create_ardour_test_program(bld, obj.includes, 'control_surface', 'test_control_surfaces', ['test/control_surfaces_test.cc']) create_ardour_test_program(bld, obj.includes, 'mtdm_test', 'test_mtdm', ['test/mtdm_test.cc']) @@ -498,6 +499,7 @@ def build(bld): test/framepos_minus_beats_test.cc test/playlist_equivalent_regions_test.cc test/playlist_layering_test.cc + test/plugins_test.cc test/region_naming_test.cc test/control_surfaces_test.cc test/mtdm_test.cc From ea0e42dee748e67feaeb84c7fe407f69c6cf740b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 12:40:34 -0400 Subject: [PATCH 54/69] Use g_stat in AudioSource::touch_peakfile for portability --- libs/ardour/audiosource.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index ff92b8977d..fc1cc23fa0 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -30,8 +30,11 @@ #include #include -#include +#include +#include + #include +#include #include #include @@ -179,7 +182,7 @@ AudioSource::touch_peakfile () { struct stat statbuf; - if (stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) { + if (g_stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) { return; } From dca2774508a577bd817a80db9b80f056d95190f1 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 12:41:01 -0400 Subject: [PATCH 55/69] Use g_utime for portability in AudioSource::touch_peakfile --- libs/ardour/audiosource.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index fc1cc23fa0..93a1c6ceb5 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -191,7 +191,7 @@ AudioSource::touch_peakfile () tbuf.actime = statbuf.st_atime; tbuf.modtime = time ((time_t) 0); - utime (peakpath.c_str(), &tbuf); + g_utime (peakpath.c_str(), &tbuf); } int From 4a8aadbbdf7e93d4c237c33ee6b79b212aa868b2 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 12:41:24 -0400 Subject: [PATCH 56/69] Use g_rename in AudioSource::rename_peakfile for portability --- libs/ardour/audiosource.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 93a1c6ceb5..92d35ab1d3 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -202,7 +202,7 @@ AudioSource::rename_peakfile (string newpath) string oldpath = peakpath; if (Glib::file_test (oldpath, Glib::FILE_TEST_EXISTS)) { - if (rename (oldpath.c_str(), newpath.c_str()) != 0) { + if (g_rename (oldpath.c_str(), newpath.c_str()) != 0) { error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg; return -1; } From 3e1c66f946fe90033277cbab2681a705fb987acb Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 12:41:53 -0400 Subject: [PATCH 57/69] Use g_stat in AudioSource::initialize_peakfile for portability --- libs/ardour/audiosource.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 92d35ab1d3..d8c25b0200 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -228,7 +228,7 @@ AudioSource::initialize_peakfile (string audio_path) peakpath = find_broken_peakfile (peakpath, audio_path); } - if (stat (peakpath.c_str(), &statbuf)) { + if (g_stat (peakpath.c_str(), &statbuf)) { if (errno != ENOENT) { /* it exists in the peaks dir, but there is some kind of error */ From a8647faca7d60ba6404239f2ebcff1631028fbad Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 12:46:35 -0400 Subject: [PATCH 58/69] Add JACK utility functions in libardour and test This contains much of the code present in the GUI EngineDialog class but refactored with some added windows bits. --- libs/ardour/ardour/jack_utils.h | 261 ++++++++ libs/ardour/jack_utils.cc | 947 ++++++++++++++++++++++++++++ libs/ardour/test/jack_utils_test.cc | 315 +++++++++ libs/ardour/test/jack_utils_test.h | 33 + libs/ardour/wscript | 14 +- 5 files changed, 1568 insertions(+), 2 deletions(-) create mode 100644 libs/ardour/ardour/jack_utils.h create mode 100644 libs/ardour/jack_utils.cc create mode 100644 libs/ardour/test/jack_utils_test.cc create mode 100644 libs/ardour/test/jack_utils_test.h diff --git a/libs/ardour/ardour/jack_utils.h b/libs/ardour/ardour/jack_utils.h new file mode 100644 index 0000000000..353724f079 --- /dev/null +++ b/libs/ardour/ardour/jack_utils.h @@ -0,0 +1,261 @@ +/* + Copyright (C) 2011 Tim Mayberry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +#include +#include +#include + +namespace ARDOUR { + + // Names for the drivers on all possible systems + extern const char * const portaudio_driver_name; + extern const char * const coreaudio_driver_name; + extern const char * const alsa_driver_name; + extern const char * const oss_driver_name; + extern const char * const freebob_driver_name; + extern const char * const ffado_driver_name; + extern const char * const netjack_driver_name; + extern const char * const dummy_driver_name; + + /** + * Get a list of possible JACK audio driver names based on platform + */ + void get_jack_audio_driver_names (std::vector& driver_names); + + /** + * Get the default JACK audio driver based on platform + */ + void get_jack_default_audio_driver_name (std::string& driver_name); + + /** + * Get a list of possible JACK midi driver names based on platform + */ + void get_jack_midi_system_names (const std::string& driver, std::vector& driver_names); + + /** + * Get the default JACK midi driver based on platform + */ + void get_jack_default_midi_system_name (const std::string& driver_name, std::string& midi_system); + + /** + * Get a list of possible samplerates supported be JACK + */ + void get_jack_sample_rate_strings (std::vector& sample_rates); + + /** + * @return The default samplerate + */ + std::string get_jack_default_sample_rate (); + + /** + * @return true if sample rate string was able to be converted + */ + bool get_jack_sample_rate_value_from_string (const std::string& srs, uint32_t& srv); + + /** + * Get a list of possible period sizes supported be JACK + */ + void get_jack_period_size_strings (std::vector& samplerates); + + /** + * @return The default period size + */ + std::string get_jack_default_period_size (); + + /** + * @return true if period size string was able to be converted + */ + bool get_jack_period_size_value_from_string (const std::string& pss, uint32_t& psv); + + /** + * These are driver specific I think, so it may require a driver arg + * in future + */ + void get_jack_dither_mode_strings (const std::string& driver, std::vector& dither_modes); + + /** + * @return The default dither mode + */ + std::string get_jack_default_dither_mode (const std::string& driver); + + /** + * @return Estimate of latency + * + * API matches current use in GUI + */ + std::string get_jack_latency_string (std::string samplerate, float periods, std::string period_size); + + /** + * @return true if a JACK server is running + */ + bool jack_server_running (); + + /** + * Key being a readable name to display in a GUI + * Value being name used in a jack commandline + */ + typedef std::map device_map_t; + + /** + * Use library specific code to find out what what devices exist for a given + * driver that might work in JACK. There is no easy way to find out what + * modules the JACK server supports so guess based on platform. For instance + * portaudio is cross-platform but we only return devices if built for + * windows etc + */ + void get_jack_alsa_device_names (device_map_t& devices); + void get_jack_portaudio_device_names (device_map_t& devices); + void get_jack_coreaudio_device_names (device_map_t& devices); + void get_jack_oss_device_names (device_map_t& devices); + void get_jack_freebob_device_names (device_map_t& devices); + void get_jack_ffado_device_names (device_map_t& devices); + void get_jack_netjack_device_names (device_map_t& devices); + void get_jack_dummy_device_names (device_map_t& devices); + + /* + * @return true if there were devices found for the driver + * + * @param driver The driver name returned by get_jack_audio_driver_names + * @param devices The map used to insert the drivers into, devices will be cleared before + * adding the available drivers + */ + bool get_jack_device_names_for_audio_driver (const std::string& driver, device_map_t& devices); + + /* + * @return a list of readable device names for a specific driver. + */ + std::vector get_jack_device_names_for_audio_driver (const std::string& driver); + + /** + * @return true if the driver supports playback and recording + * on separate devices + */ + bool get_jack_audio_driver_supports_two_devices (const std::string& driver); + + bool get_jack_audio_driver_supports_latency_adjustment (const std::string& driver); + + bool get_jack_audio_driver_supports_setting_period_count (const std::string& driver); + + /** + * The possible names to use to try and find servers, this includes + * any file extensions like .exe on Windows + * + * @return true if the JACK application names for this platform could be guessed + */ + bool get_jack_server_application_names (std::vector& server_names); + + /** + * Sets the PATH environment variable to contain directories likely to contain + * JACK servers so that if the JACK server is auto-started it can find the server + * executable. + * + * This is only modifies PATH on the mac at the moment. + */ + void set_path_env_for_jack_autostart (const std::vector&); + + /** + * Get absolute paths to directories that might contain JACK servers on the system + * + * @return true if !server_paths.empty() + */ + bool get_jack_server_dir_paths (std::vector& server_dir_paths); + + /** + * Get absolute paths to JACK servers on the system + * + * @return true if a server was found + */ + bool get_jack_server_paths (const std::vector& server_dir_paths, + const std::vector& server_names, + std::vector& server_paths); + + + bool get_jack_server_paths (std::vector& server_paths); + + /** + * Get absolute path to default JACK server + */ + bool get_jack_default_server_path (std::string& server_path); + + /** + * @return The name of the jack server config file + */ + std::string get_jack_server_config_file_name (); + + std::string get_jack_server_user_config_dir_path (); + + std::string get_jack_server_user_config_file_path (); + + bool write_jack_config_file (const std::string& config_file_path, const std::string& command_line); + + struct JackCommandLineOptions { + + // see implementation for defaults + JackCommandLineOptions (); + + //operator bool + //operator ostream + + std::string server_path; + uint32_t timeout; + bool no_mlock; + uint32_t ports_max; + bool realtime; + uint32_t priority; + bool unlock_gui_libs; + bool verbose; + bool temporary; + bool playback_only; + bool capture_only; + std::string driver; + std::string input_device; + std::string output_device; + uint32_t num_periods; + uint32_t period_size; + uint32_t samplerate; + uint32_t input_latency; + uint32_t output_latency; + bool hardware_metering; + bool hardware_monitoring; + std::string dither_mode; + bool force16_bit; + bool soft_mode; + std::string midi_driver; + }; + + /** + * @return true if able to build a valid command line based on options + */ + bool get_jack_command_line_string (const JackCommandLineOptions& options, std::string& command_line); + + /** + * We don't need this at the moment because the gui stores all its settings + */ + //std::string get_jack_command_line_from_config_file (const std::string& config_file_path); + + /** + * Temporary for WIN32 only as jack_client_open doesn't start the server on that platform + * + * @return true if server was able to be started + */ + bool start_jack_server (const std::string& command_line); + +} diff --git a/libs/ardour/jack_utils.cc b/libs/ardour/jack_utils.cc new file mode 100644 index 0000000000..29f7ca4f3e --- /dev/null +++ b/libs/ardour/jack_utils.cc @@ -0,0 +1,947 @@ +/* + Copyright (C) 2010 Paul Davis + Copyright (C) 2011 Tim Mayberry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifdef WAF_BUILD +#include "libardour-config.h" +#endif + +#ifdef HAVE_ALSA +#include +#endif + +#ifdef __APPLE__ +#include +#include +#include +#include +#endif + +#ifdef HAVE_PORTAUDIO +#include +#endif + +#include + +#include + +#include + +#include + +#include "pbd/epa.h" +#include "pbd/error.h" +#include "pbd/convert.h" +#include "pbd/file_utils.h" +#include "pbd/search_path.h" + +#include "ardour/jack_utils.h" + +#ifdef __APPLE +#include +#endif + +#include "i18n.h" + +using namespace std; +using namespace PBD; + +namespace ARDOUR { + // The pretty driver names + const char * const portaudio_driver_name = X_("Portaudio"); + const char * const coreaudio_driver_name = X_("CoreAudio"); + const char * const alsa_driver_name = X_("ALSA"); + const char * const oss_driver_name = X_("OSS"); + const char * const freebob_driver_name = X_("FreeBoB"); + const char * const ffado_driver_name = X_("FFADO"); + const char * const netjack_driver_name = X_("NetJACK"); + const char * const dummy_driver_name = X_("Dummy"); +} + +namespace { + + // The real driver names + const char * const portaudio_driver_command_line_name = X_("portaudio"); + const char * const coreaudio_driver_command_line_name = X_("coreaudio"); + const char * const alsa_driver_command_line_name = X_("alsa"); + const char * const oss_driver_command_line_name = X_("oss"); + const char * const freebob_driver_command_line_name = X_("freebob"); + const char * const ffado_driver_command_line_name = X_("firewire"); + const char * const netjack_driver_command_line_name = X_("netjack"); + const char * const dummy_driver_command_line_name = X_("dummy"); + + // should we provide more "pretty" names like above? + const char * const alsaseq_midi_driver_name = X_("seq"); + const char * const alsaraw_midi_driver_name = X_("raw"); + const char * const winmme_midi_driver_name = X_("winmme"); + const char * const coremidi_midi_driver_name = X_("coremidi"); + + // this should probably be translated + const char * const default_device_name = X_("Default"); +} + +std::string +get_none_string () +{ + return _("None"); +} + +void +ARDOUR::get_jack_audio_driver_names (vector& audio_driver_names) +{ +#ifdef WIN32 + audio_driver_names.push_back (portaudio_driver_name); +#elif __APPLE__ + audio_driver_names.push_back (coreaudio_driver_name); +#else +#ifdef HAVE_ALSA + audio_driver_names.push_back (alsa_driver_name); +#endif + audio_driver_names.push_back (oss_driver_name); + audio_driver_names.push_back (freebob_driver_name); + audio_driver_names.push_back (ffado_driver_name); +#endif + audio_driver_names.push_back (netjack_driver_name); + audio_driver_names.push_back (dummy_driver_name); +} + +void +ARDOUR::get_jack_default_audio_driver_name (string& audio_driver_name) +{ + vector drivers; + get_jack_audio_driver_names (drivers); + audio_driver_name = drivers.front (); +} + +void +ARDOUR::get_jack_midi_system_names (const string& driver, vector& midi_system_names) +{ + midi_system_names.push_back (get_none_string ()); +#ifdef WIN32 + midi_system_names.push_back (winmme_midi_driver_name); +#elif __APPLE__ + midi_system_names.push_back (coreaudio_midi_driver_name); +#else +#ifdef HAVE_ALSA + if (driver == alsa_driver_name) { + midi_system_names.push_back (alsaseq_midi_driver_name); + midi_system_names.push_back (alsaraw_midi_driver_name); + } +#endif +#endif +} + +void +ARDOUR::get_jack_default_midi_system_name (const string& driver, string& midi_system_name) +{ + vector drivers; + get_jack_midi_system_names (driver, drivers); + midi_system_name = drivers.front (); +} + +void +ARDOUR::get_jack_sample_rate_strings (vector& samplerates) +{ + // do these really need to be translated? + samplerates.push_back (_("8000Hz")); + samplerates.push_back (_("22050Hz")); + samplerates.push_back (_("44100Hz")); + samplerates.push_back (_("48000Hz")); + samplerates.push_back (_("88200Hz")); + samplerates.push_back (_("96000Hz")); + samplerates.push_back (_("192000Hz")); +} + +string +ARDOUR::get_jack_default_sample_rate () +{ + return _("48000Hz"); +} + +void +ARDOUR::get_jack_period_size_strings (std::vector& period_sizes) +{ + period_sizes.push_back ("32"); + period_sizes.push_back ("64"); + period_sizes.push_back ("128"); + period_sizes.push_back ("256"); + period_sizes.push_back ("512"); + period_sizes.push_back ("1024"); + period_sizes.push_back ("2048"); + period_sizes.push_back ("4096"); + period_sizes.push_back ("8192"); +} + +string +ARDOUR::get_jack_default_period_size () +{ + return "1024"; +} + +void +ARDOUR::get_jack_dither_mode_strings (const string& driver, vector& dither_modes) +{ + dither_modes.push_back (get_none_string ()); + + if (driver == alsa_driver_name ) { + dither_modes.push_back (_("Triangular")); + dither_modes.push_back (_("Rectangular")); + dither_modes.push_back (_("Shaped")); + } +} + +string +ARDOUR::get_jack_default_dither_mode (const string& driver) +{ + return get_none_string (); +} + +string +ARDOUR::get_jack_latency_string (string samplerate, float periods, string period_size) +{ + uint32_t rate = atoi (samplerate); + float psize = atof (period_size); + + char buf[32]; + snprintf (buf, sizeof(buf), "%.1fmsec", (periods * psize) / (rate/1000.0)); + + return buf; +} + +bool +get_jack_command_line_audio_driver_name (const string& driver_name, string& command_line_name) +{ + using namespace ARDOUR; + if (driver_name == portaudio_driver_name) { + command_line_name = portaudio_driver_command_line_name; + return true; + } else if (driver_name == coreaudio_driver_name) { + command_line_name = coreaudio_driver_command_line_name; + return true; + } else if (driver_name == alsa_driver_name) { + command_line_name = alsa_driver_command_line_name; + return true; + } else if (driver_name == oss_driver_name) { + command_line_name = oss_driver_command_line_name; + return true; + } else if (driver_name == freebob_driver_name) { + command_line_name = freebob_driver_command_line_name; + return true; + } else if (driver_name == ffado_driver_name) { + command_line_name = ffado_driver_command_line_name; + return true; + } else if (driver_name == netjack_driver_name) { + command_line_name = netjack_driver_command_line_name; + return true; + } else if (driver_name == dummy_driver_name) { + command_line_name = dummy_driver_command_line_name; + return true; + } + return false; +} + +bool +get_jack_command_line_audio_device_name (const string& driver_name, + const string& device_name, string& command_line_device_name) +{ + using namespace ARDOUR; + device_map_t devices; + + get_jack_device_names_for_audio_driver (driver_name, devices); + + for (device_map_t::const_iterator i = devices.begin (); i != devices.end(); ++i) { + if (i->first == device_name) { + command_line_device_name = i->second; + return true; + } + } + return false; +} + +bool +get_jack_command_line_dither_mode (const string& dither_mode, string& command_line_dither_mode) +{ + using namespace ARDOUR; + + if (dither_mode == _("Triangular")) { + command_line_dither_mode = "triangular"; + return true; + } else if (dither_mode == _("Rectangular")) { + command_line_dither_mode = "rectangular"; + return true; + } else if (dither_mode == _("Shaped")) { + command_line_dither_mode = "shaped"; + return true; + } + + return false; +} + +bool +ARDOUR::jack_server_running () +{ + EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa (); + boost::scoped_ptr current_epa; + + /* revert all environment settings back to whatever they were when ardour started + */ + + if (global_epa) { + current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */ + global_epa->restore (); + } + + jack_status_t status; + jack_client_t* c = jack_client_open ("ardourprobe", JackNoStartServer, &status); + + if (status == 0) { + jack_client_close (c); + return true; + } + return false; + +} + +void +ARDOUR::get_jack_alsa_device_names (device_map_t& devices) +{ +#ifdef HAVE_ALSA + snd_ctl_t *handle; + snd_ctl_card_info_t *info; + snd_pcm_info_t *pcminfo; + snd_ctl_card_info_alloca(&info); + snd_pcm_info_alloca(&pcminfo); + string devname; + int cardnum = -1; + int device = -1; + + while (snd_card_next (&cardnum) >= 0 && cardnum >= 0) { + + devname = "hw:"; + devname += PBD::to_string (cardnum, std::dec); + + if (snd_ctl_open (&handle, devname.c_str(), 0) >= 0 && snd_ctl_card_info (handle, info) >= 0) { + + while (snd_ctl_pcm_next_device (handle, &device) >= 0 && device >= 0) { + + snd_pcm_info_set_device (pcminfo, device); + snd_pcm_info_set_subdevice (pcminfo, 0); + snd_pcm_info_set_stream (pcminfo, SND_PCM_STREAM_PLAYBACK); + + if (snd_ctl_pcm_info (handle, pcminfo) >= 0) { + devname += ','; + devname += PBD::to_string (device, std::dec); + devices.insert (std::make_pair (snd_pcm_info_get_name (pcminfo), devname)); + } + } + + snd_ctl_close(handle); + } + } +#endif +} + +#ifdef __APPLE__ +static OSStatus +getDeviceUIDFromID( AudioDeviceID id, char *name, size_t nsize) +{ + UInt32 size = sizeof(CFStringRef); + CFStringRef UI; + OSStatus res = AudioDeviceGetProperty(id, 0, false, + kAudioDevicePropertyDeviceUID, &size, &UI); + if (res == noErr) + CFStringGetCString(UI,name,nsize,CFStringGetSystemEncoding()); + CFRelease(UI); + return res; +} +#endif + +void +ARDOUR::get_jack_coreaudio_device_names (device_map_t& devices) +{ +#ifdef __APPLE__ + // Find out how many Core Audio devices are there, if any... + // (code snippet gently "borrowed" from St?hane Letz jackdmp;) + OSStatus err; + Boolean isWritable; + UInt32 outSize = sizeof(isWritable); + + err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, + &outSize, &isWritable); + if (err == noErr) { + // Calculate the number of device available... + int numCoreDevices = outSize / sizeof(AudioDeviceID); + // Make space for the devices we are about to get... + AudioDeviceID *coreDeviceIDs = new AudioDeviceID [numCoreDevices]; + err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, + &outSize, (void *) coreDeviceIDs); + if (err == noErr) { + // Look for the CoreAudio device name... + char coreDeviceName[256]; + UInt32 nameSize; + + for (int i = 0; i < numCoreDevices; i++) { + + nameSize = sizeof (coreDeviceName); + + /* enforce duplex devices only */ + + err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], + 0, true, kAudioDevicePropertyStreams, + &outSize, &isWritable); + + if (err != noErr || outSize == 0) { + continue; + } + + err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], + 0, false, kAudioDevicePropertyStreams, + &outSize, &isWritable); + + if (err != noErr || outSize == 0) { + continue; + } + + err = AudioDeviceGetPropertyInfo(coreDeviceIDs[i], + 0, true, kAudioDevicePropertyDeviceName, + &outSize, &isWritable); + if (err == noErr) { + err = AudioDeviceGetProperty(coreDeviceIDs[i], + 0, true, kAudioDevicePropertyDeviceName, + &nameSize, (void *) coreDeviceName); + if (err == noErr) { + char drivername[128]; + + // this returns the unique id for the device + // that must be used on the commandline for jack + + if (getDeviceUIDFromID(coreDeviceIDs[i], drivername, sizeof (drivername)) == noErr) { + devices.insert (make_pair (coreDeviceName, drivername)); + } + } + } + } + } + delete [] coreDeviceIDs; + } +#endif +} + +void +ARDOUR::get_jack_portaudio_device_names (device_map_t& devices) +{ +#ifdef HAVE_PORTAUDIO + if (Pa_Initialize() != paNoError) { + return; + } + + for (PaDeviceIndex i = 0; i < Pa_GetDeviceCount (); ++i) { + string api_name; + string readable_name; + string jack_device_name; + const PaDeviceInfo* device_info = Pa_GetDeviceInfo(i); + + if (device_info != NULL) { // it should never be ? + api_name = Pa_GetHostApiInfo (device_info->hostApi)->name; + readable_name = api_name + " " + device_info->name; + jack_device_name = api_name + "::" + device_info->name; + devices.insert (make_pair (readable_name, jack_device_name)); + } + } + Pa_Terminate(); +#endif +} + +void +ARDOUR::get_jack_oss_device_names (device_map_t& devices) +{ + devices.insert (make_pair (default_device_name, default_device_name)); +} + +void +ARDOUR::get_jack_freebob_device_names (device_map_t& devices) +{ + devices.insert (make_pair (default_device_name, default_device_name)); +} + +void +ARDOUR::get_jack_ffado_device_names (device_map_t& devices) +{ + devices.insert (make_pair (default_device_name, default_device_name)); +} + +void +ARDOUR::get_jack_netjack_device_names (device_map_t& devices) +{ + devices.insert (make_pair (default_device_name, default_device_name)); +} + +void +ARDOUR::get_jack_dummy_device_names (device_map_t& devices) +{ + devices.insert (make_pair (default_device_name, default_device_name)); +} + +bool +ARDOUR::get_jack_device_names_for_audio_driver (const string& driver_name, device_map_t& devices) +{ + devices.clear(); + + if (driver_name == portaudio_driver_name) { + get_jack_portaudio_device_names (devices); + } else if (driver_name == coreaudio_driver_name) { + get_jack_coreaudio_device_names (devices); + } else if (driver_name == alsa_driver_name) { + get_jack_alsa_device_names (devices); + } else if (driver_name == oss_driver_name) { + get_jack_oss_device_names (devices); + } else if (driver_name == freebob_driver_name) { + get_jack_freebob_device_names (devices); + } else if (driver_name == ffado_driver_name) { + get_jack_ffado_device_names (devices); + } else if (driver_name == netjack_driver_name) { + get_jack_netjack_device_names (devices); + } else if (driver_name == dummy_driver_name) { + get_jack_dummy_device_names (devices); + } + + return !devices.empty(); +} + + +std::vector +ARDOUR::get_jack_device_names_for_audio_driver (const string& driver_name) +{ + std::vector readable_names; + device_map_t devices; + + get_jack_device_names_for_audio_driver (driver_name, devices); + + for (device_map_t::const_iterator i = devices.begin (); i != devices.end(); ++i) { + readable_names.push_back (i->first); + } + + return readable_names; +} + +bool +ARDOUR::get_jack_audio_driver_supports_two_devices (const string& driver) +{ + return (driver == alsa_driver_name || driver == oss_driver_name); +} + +bool +ARDOUR::get_jack_audio_driver_supports_latency_adjustment (const string& driver) +{ + return (driver == alsa_driver_name || driver == coreaudio_driver_name || + driver == ffado_driver_name || driver == portaudio_driver_name); +} + +bool +ARDOUR::get_jack_audio_driver_supports_setting_period_count (const string& driver) +{ + return !(driver == dummy_driver_name || driver == coreaudio_driver_name || + driver == portaudio_driver_name); +} + +bool +ARDOUR::get_jack_server_application_names (std::vector& server_names) +{ +#ifdef WIN32 + server_names.push_back ("jackd.exe"); +#else + server_names.push_back ("jackd"); + server_names.push_back ("jackdmp"); +#endif + return !server_names.empty(); +} + +void +ARDOUR::set_path_env_for_jack_autostart (const vector& dirs) +{ +#ifdef __APPLE__ + // push it back into the environment so that auto-started JACK can find it. + // XXX why can't we just expect OS X users to have PATH set correctly? we can't ... + setenv ("PATH", SearchPath(dirs).to_string(), 1); +#endif +} + +bool +ARDOUR::get_jack_server_dir_paths (vector& server_dir_paths) +{ +#ifdef __APPLE__ + /* this magic lets us finds the path to the OSX bundle, and then + we infer JACK's location from there + */ + + char execpath[MAXPATHLEN+1]; + uint32_t pathsz = sizeof (execpath); + + _NSGetExecutablePath (execpath, &pathsz); + + server_dir_paths.push_back (Glib::path_get_dirname (execpath)); +#endif + + SearchPath sp(string(g_getenv("PATH"))); + +#ifdef WIN32 + gchar *install_dir = g_win32_get_package_installation_directory_of_module (NULL); + if (install_dir) { + sp.push_back (install_dir); + g_free (install_dir); + } + // don't try and use a system wide JACK install yet. +#else + if (sp.empty()) { + sp.push_back ("/usr/bin"); + sp.push_back ("/bin"); + sp.push_back ("/usr/local/bin"); + sp.push_back ("/opt/local/bin"); + } +#endif + + std::copy (sp.begin(), sp.end(), std::back_inserter(server_dir_paths)); + + return !server_dir_paths.empty(); +} + +bool +ARDOUR::get_jack_server_paths (const vector& server_dir_paths, + const vector& server_names, + vector& server_paths) +{ + for (vector::const_iterator i = server_names.begin(); i != server_names.end(); ++i) { + find_matching_files_in_directories (server_dir_paths, Glib::PatternSpec(*i), server_paths); + } + return !server_paths.empty(); +} + +bool +ARDOUR::get_jack_server_paths (vector& server_paths) +{ + vector server_dirs; + + if (!get_jack_server_dir_paths (server_dirs)) { + return false; + } + + vector server_names; + + if (!get_jack_server_application_names (server_names)) { + return false; + } + + if (!get_jack_server_paths (server_dirs, server_names, server_paths)) { + return false; + } + + return !server_paths.empty(); +} + +bool +ARDOUR::get_jack_default_server_path (std::string& server_path) +{ + vector server_paths; + + if (!get_jack_server_paths (server_paths)) { + return false; + } + + server_path = server_paths.front (); + return true; +} + +string +quote_string (const string& str) +{ + return "\"" + str + "\""; +} + +ARDOUR::JackCommandLineOptions::JackCommandLineOptions () + : server_path () + , timeout(0) + , no_mlock(false) + , ports_max(128) + , realtime(true) + , priority(0) + , unlock_gui_libs(false) + , verbose(false) + , temporary(true) + , driver() + , input_device() + , output_device() + , num_periods(2) + , period_size(1024) + , samplerate(48000) + , input_latency(0) + , output_latency(0) + , hardware_metering(false) + , hardware_monitoring(false) + , dither_mode() + , force16_bit(false) + , soft_mode(false) + , midi_driver() +{ + +} + +bool +ARDOUR::get_jack_command_line_string (const JackCommandLineOptions& options, string& command_line) +{ + vector args; + + args.push_back (options.server_path); + +#ifdef WIN32 + // must use sync mode on windows + args.push_back ("-S"); + + // this needs to be added now on windows + if (!options.midi_driver.empty () && options.midi_driver != get_none_string ()) { + args.push_back ("-X"); + args.push_back (options.midi_driver); + } +#endif + + if (options.timeout) { + args.push_back ("-t"); + args.push_back (to_string (options.timeout, std::dec)); + } + + if (options.no_mlock) { + args.push_back ("-m"); + } + + args.push_back ("-p"); + args.push_back (to_string(options.ports_max, std::dec)); + + if (options.realtime) { + args.push_back ("-R"); + if (options.priority != 0) { + args.push_back ("-P"); + args.push_back (to_string(options.priority, std::dec)); + } + } else { + args.push_back ("-r"); + } + + if (options.unlock_gui_libs) { + args.push_back ("-u"); + } + + if (options.verbose) { + args.push_back ("-v"); + } + +#ifndef WIN32 + if (options.temporary) { + args.push_back ("-T"); + } +#endif + + string command_line_driver_name; + + if (!get_jack_command_line_audio_driver_name (options.driver, command_line_driver_name)) { + return false; + } + + args.push_back ("-d"); + args.push_back (command_line_driver_name); + + if (options.output_device.empty() && options.input_device.empty()) { + return false; + } + + string command_line_input_device_name; + string command_line_output_device_name; + + if (!get_jack_command_line_audio_device_name (options.driver, + options.input_device, command_line_input_device_name)) + { + return false; + } + + if (!get_jack_command_line_audio_device_name (options.driver, + options.output_device, command_line_output_device_name)) + { + return false; + } + + if (options.input_device.empty()) { + // playback only + if (options.output_device.empty()) { + return false; + } + args.push_back ("-P"); + } else if (options.output_device.empty()) { + // capture only + if (options.input_device.empty()) { + return false; + } + args.push_back ("-C"); + } else if (options.input_device != options.output_device) { + // capture and playback on two devices if supported + if (get_jack_audio_driver_supports_two_devices (options.driver)) { + args.push_back ("-C"); + args.push_back (command_line_input_device_name); + args.push_back ("-P"); + args.push_back (command_line_output_device_name); + } else { + return false; + } + } + + if (get_jack_audio_driver_supports_setting_period_count (options.driver)) { + args.push_back ("-n"); + args.push_back (to_string (options.num_periods, std::dec)); + } + + args.push_back ("-r"); + args.push_back (to_string (options.samplerate, std::dec)); + + args.push_back ("-p"); + args.push_back (to_string (options.period_size, std::dec)); + + if (get_jack_audio_driver_supports_latency_adjustment (options.driver)) { + if (options.input_latency) { + args.push_back ("-I"); + args.push_back (to_string (options.input_latency, std::dec)); + } + if (options.output_latency) { + args.push_back ("-0"); + args.push_back (to_string (options.output_latency, std::dec)); + } + } + + if (options.input_device == options.output_device && options.input_device != default_device_name) { + args.push_back ("-d"); + args.push_back (command_line_input_device_name); + } + + if (options.driver == alsa_driver_name) { + if (options.hardware_metering) { + args.push_back ("-M"); + } + if (options.hardware_monitoring) { + args.push_back ("-H"); + } + + string command_line_dither_mode; + if (get_jack_command_line_dither_mode (options.dither_mode, command_line_dither_mode)) { + args.push_back ("-z"); + args.push_back (command_line_dither_mode); + } + if (options.force16_bit) { + args.push_back ("-S"); + } + if (options.soft_mode) { + args.push_back ("-s"); + } + + if (!options.midi_driver.empty() && options.midi_driver != get_none_string ()) { + args.push_back ("-X"); + args.push_back (options.midi_driver); + } + } + + ostringstream oss; + + for (vector::const_iterator i = args.begin(); i != args.end();) { +#ifdef WIN32 + oss << quote_string (*i); +#else + oss << *i; +#endif + if (++i != args.end()) oss << ' '; + } + + command_line = oss.str(); + return true; +} + +string +ARDOUR::get_jack_server_config_file_name () +{ + return ".jackdrc"; +} + +std::string +ARDOUR::get_jack_server_user_config_dir_path () +{ + return Glib::get_home_dir (); +} + +std::string +ARDOUR::get_jack_server_user_config_file_path () +{ + return Glib::build_filename (get_jack_server_user_config_dir_path (), get_jack_server_config_file_name ()); +} + +bool +ARDOUR::write_jack_config_file (const std::string& config_file_path, const string& command_line) +{ + ofstream jackdrc (config_file_path.c_str()); + + if (!jackdrc) { + error << string_compose (_("cannot open JACK rc file %1 to store parameters"), config_file_path) << endmsg; + return false; + } + + jackdrc << command_line << endl; + jackdrc.close (); + return true; +} + +bool +ARDOUR::start_jack_server (const string& command_line) +{ +#ifdef WIN32 + STARTUPINFO si; + PROCESS_INFORMATION pi; + char * cmdline = g_strdup (command_line.c_str()); + + memset (&si, 0, sizeof (si)); + si.cb = sizeof (&si); + memset (&pi, 0, sizeof (pi)); + + if (!CreateProcess ( + NULL, // No module name, use command line + cmdline, + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // set handle inheritance to false + 0, // No creation flags + NULL, // Use parents environment block + NULL, // Use parents starting directory + &si, + &pi)) + { + error << string_compose ("cannot start JACK server: %s", g_win32_error_message (GetLastError ())) << endmsg; + } + + g_free (cmdline); + + // wait for 2 seconds for server to start + for (int i = 0; i < 8; ++i) { + Sleep (250); // 1/4 second + if (jack_server_running ()) return true; + } +#endif + return false; +} diff --git a/libs/ardour/test/jack_utils_test.cc b/libs/ardour/test/jack_utils_test.cc new file mode 100644 index 0000000000..ed80237f78 --- /dev/null +++ b/libs/ardour/test/jack_utils_test.cc @@ -0,0 +1,315 @@ + +#include + +#ifdef WIN32 +#include // only for Sleep +#endif + +#include + +#include "ardour/jack_utils.h" + +#include "jack_utils_test.h" + +CPPUNIT_TEST_SUITE_REGISTRATION (JackUtilsTest); + +using namespace std; +using namespace ARDOUR; + +void +JackUtilsTest::test_driver_names () +{ + vector driver_names; + + get_jack_audio_driver_names (driver_names); + + CPPUNIT_ASSERT(!driver_names.empty()); + + cout << endl; + cout << "Number of possible JACK Audio drivers found on this system: " << driver_names.size () << endl; + + for (vector::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) { + cout << "JACK Audio driver found: " << *i << endl; + } + + string default_audio_driver; + get_jack_default_audio_driver_name (default_audio_driver); + + cout << "The default audio driver on this system is: " << default_audio_driver << endl; + + driver_names.clear(); + + get_jack_midi_system_names (default_audio_driver, driver_names); + + CPPUNIT_ASSERT(!driver_names.empty()); + + cout << "Number of possible JACK MIDI drivers found on this system for default audio driver: " << driver_names.size () << endl; + + for (vector::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) { + cout << "JACK MIDI driver found: " << *i << endl; + } + + string default_midi_driver; + get_jack_default_midi_system_name (default_audio_driver, default_midi_driver); + + cout << "The default midi driver on this system is: " << default_midi_driver << endl; +} + +string +devices_string (const vector& devices) +{ + std::string str; + for (vector::const_iterator i = devices.begin(); i != devices.end();) { + str += *i; + if (++i != devices.end()) str += ", "; + } + return str; +} + +void +JackUtilsTest::test_device_names () +{ + vector driver_names; + + get_jack_audio_driver_names (driver_names); + + CPPUNIT_ASSERT(!driver_names.empty()); + + cout << endl; + + for (vector::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) { + string devices = devices_string (get_jack_device_names_for_audio_driver (*i)); + cout << "JACK Audio driver found: " << *i << " with devices: " << devices << endl; + } +} + +void +JackUtilsTest::test_samplerates () +{ + vector samplerates; + + get_jack_sample_rate_strings (samplerates); + cout << endl; + cout << "Number of possible Samplerates supported by JACK: " << samplerates.size () << endl; + + for (vector::const_iterator i = samplerates.begin(); i != samplerates.end(); ++i) { + cout << "Samplerate: " << *i << endl; + } +} + +void +JackUtilsTest::test_period_sizes () +{ + vector period_sizes; + + get_jack_period_size_strings (period_sizes); + cout << endl; + cout << "Number of possible Period sizes supported by JACK: " << period_sizes.size () << endl; + + for (vector::const_iterator i = period_sizes.begin(); i != period_sizes.end(); ++i) { + cout << "Period size: " << *i << endl; + } +} + +void +JackUtilsTest::test_dither_modes () +{ + vector driver_names; + + get_jack_audio_driver_names (driver_names); + + CPPUNIT_ASSERT(!driver_names.empty()); + + cout << endl; + + for (vector::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) { + vector dither_modes; + + get_jack_dither_mode_strings (*i, dither_modes); + cout << "Number of possible Dither Modes supported by JACK driver " << *i << + ": " << dither_modes.size () << endl; + for (vector::const_iterator j = dither_modes.begin(); j != dither_modes.end(); ++j) { + cout << "Dither Mode: " << *j << endl; + } + cout << endl; + } + +} + +void +JackUtilsTest::test_connect_server () +{ + cout << endl; + if (jack_server_running ()) { + cout << "Jack server running " << endl; + } else { + cout << "Jack server not running " << endl; + } +} + +void +JackUtilsTest::test_set_jack_path_env () +{ + cout << endl; + + bool path_env_set = false; + + string path_env = Glib::getenv ("PATH", path_env_set); + + if (path_env_set) { + cout << "PATH env set to: " << path_env << endl; + } else { + cout << "PATH env not set" << endl; + } + vector server_dirs; + get_jack_server_dir_paths (server_dirs); + set_path_env_for_jack_autostart (server_dirs); + + path_env_set = false; + + path_env = Glib::getenv ("PATH", path_env_set); + + CPPUNIT_ASSERT (path_env_set); + + cout << "After set_jack_path_env PATH env set to: " << path_env << endl; +} + +void +JackUtilsTest::test_server_paths () +{ + cout << endl; + + vector server_dirs; + + CPPUNIT_ASSERT (get_jack_server_dir_paths (server_dirs)); + + cout << "Number of Directories that may contain JACK servers: " << server_dirs.size () << endl; + + for (vector::const_iterator i = server_dirs.begin(); i != server_dirs.end(); ++i) { + cout << "JACK server directory path: " << *i << endl; + } + + vector server_names; + + CPPUNIT_ASSERT (get_jack_server_application_names (server_names)); + + cout << "Number of possible JACK server names on this system: " << server_names.size () << endl; + + for (vector::const_iterator i = server_names.begin(); i != server_names.end(); ++i) { + cout << "JACK server name: " << *i << endl; + } + + vector server_paths; + + CPPUNIT_ASSERT (get_jack_server_paths (server_dirs, server_names, server_paths)); + + cout << "Number of JACK servers on this system: " << server_paths.size () << endl; + + for (vector::const_iterator i = server_paths.begin(); i != server_paths.end(); ++i) { + cout << "JACK server path: " << *i << endl; + } + + vector server_paths2; + + CPPUNIT_ASSERT (get_jack_server_paths (server_paths2)); + + CPPUNIT_ASSERT (server_paths.size () == server_paths2.size ()); + + std::string default_server_path; + + CPPUNIT_ASSERT (get_jack_default_server_path (default_server_path)); + + cout << "The default JACK server on this system: " << default_server_path << endl; +} + +void +JackUtilsTest::test_config () +{ + +} + +void +JackUtilsTest::test_command_line () +{ + cout << endl; + + JackCommandLineOptions options; + + CPPUNIT_ASSERT (get_jack_default_server_path (options.server_path)); + + get_jack_default_audio_driver_name (options.driver); + + string command_line; + + // should fail, haven't set any device yet + CPPUNIT_ASSERT (!get_jack_command_line_string (options, command_line)); + + vector devices = get_jack_device_names_for_audio_driver (options.driver); + + if (!devices.empty()) { + options.input_device = devices.front (); + options.output_device = devices.front (); + } else { + cout << "No audio devices available using default JACK driver using Dummy driver" << endl; + options.driver = dummy_driver_name; + devices = get_jack_device_names_for_audio_driver (options.driver); + CPPUNIT_ASSERT (!devices.empty ()); + options.input_device = devices.front (); + options.output_device = devices.front (); + } + + options.input_device = devices.front (); + options.output_device = devices.front (); + + string midi_driver; + + get_jack_default_midi_system_name (options.driver, options.midi_driver); + + // this at least should create a valid jack command line + CPPUNIT_ASSERT (get_jack_command_line_string (options, command_line)); + + cout << "Default JACK command line: " << command_line << endl; +} + +void +JackUtilsTest::test_start_server () +{ +#ifdef WIN32 + cout << endl; + + JackCommandLineOptions options; + + CPPUNIT_ASSERT (get_jack_default_server_path (options.server_path)); + + cout << "Starting JACK server at path: " << options.server_path << endl; + + get_jack_default_audio_driver_name (options.driver); + + vector devices = get_jack_device_names_for_audio_driver (options.driver); + + if (!devices.empty()) { + options.input_device = devices.front (); + options.output_device = devices.front (); + } else { + cout << "No audio devices available using default JACK driver using Dummy driver" << endl; + options.driver = dummy_driver_name; + devices = get_jack_device_names_for_audio_driver (options.driver); + CPPUNIT_ASSERT (!devices.empty ()); + options.input_device = devices.front (); + options.output_device = devices.front (); + } + + string command_line; + // this at least should create a valid jack command line + CPPUNIT_ASSERT (get_jack_command_line_string (options, command_line)); + + cout << "Calling start_jack_server with command line: " << command_line << endl; + + CPPUNIT_ASSERT (start_jack_server (command_line)); + + // sleep for 10 seconds + Sleep (10*1000); + + CPPUNIT_ASSERT (jack_server_running ()); +#endif +} diff --git a/libs/ardour/test/jack_utils_test.h b/libs/ardour/test/jack_utils_test.h new file mode 100644 index 0000000000..6a42d1d015 --- /dev/null +++ b/libs/ardour/test/jack_utils_test.h @@ -0,0 +1,33 @@ + +#include +#include + +class JackUtilsTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE (JackUtilsTest); + CPPUNIT_TEST (test_driver_names); + CPPUNIT_TEST (test_device_names); + CPPUNIT_TEST (test_samplerates); + CPPUNIT_TEST (test_period_sizes); + CPPUNIT_TEST (test_dither_modes); + CPPUNIT_TEST (test_connect_server); + CPPUNIT_TEST (test_set_jack_path_env); + CPPUNIT_TEST (test_server_paths); + CPPUNIT_TEST (test_config); + CPPUNIT_TEST (test_command_line); + CPPUNIT_TEST (test_start_server); + CPPUNIT_TEST_SUITE_END (); + +public: + void test_driver_names (); + void test_device_names (); + void test_samplerates (); + void test_period_sizes (); + void test_dither_modes (); + void test_connect_server (); + void test_set_jack_path_env (); + void test_server_paths (); + void test_config (); + void test_command_line (); + void test_start_server (); +}; diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 256ff1c6c0..3afd4ce552 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -2,6 +2,7 @@ from waflib.extras import autowaf as autowaf from waflib import Options import os +import sys import re import subprocess @@ -99,6 +100,7 @@ libardour_sources = [ 'io.cc', 'io_processor.cc', 'jack_slave.cc', + 'jack_utils.cc', 'kmeterdsp.cc', 'ladspa_plugin.cc', 'ladspa_search_path.cc', @@ -240,6 +242,12 @@ def configure(conf): atleast_version='0.3.2') autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.118.2') + if Options.options.dist_target == 'auto': + if re.search ("linux", sys.platform) != None: + autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA') + if Options.options.dist_target == 'mingw': + autowaf.check_pkg(conf, 'portaudio-2.0', uselib_store='PORTAUDIO', + atleast_version='19') autowaf.check_pkg(conf, 'libxml-2.0', uselib_store='XML') autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', atleast_version='0.4.0') @@ -379,8 +387,8 @@ def build(bld): obj.name = 'ardour' obj.target = 'ardour' obj.uselib = ['GLIBMM','GTHREAD','AUBIO','SIGCPP','XML','UUID', - 'JACK','SNDFILE','SAMPLERATE','LRDF','AUDIOUNITS', - 'OSX','BOOST','CURL','DL'] + 'JACK', 'ALSA', 'PORTAUDIO', 'SNDFILE','SAMPLERATE','LRDF', + 'AUDIOUNITS', 'OSX','BOOST','CURL','DL'] obj.use = ['libpbd','libmidipp','libevoral','libvamphost', 'libvampplugin','libtaglib','librubberband', 'libaudiographer','libltc'] @@ -479,6 +487,7 @@ def build(bld): create_ardour_test_program(bld, obj.includes, 'framewalk_to_beats', 'test_framewalk_to_beats', ['test/framewalk_to_beats_test.cc']) create_ardour_test_program(bld, obj.includes, 'framepos_plus_beats', 'test_framepos_plus_beats', ['test/framepos_plus_beats_test.cc']) create_ardour_test_program(bld, obj.includes, 'framepos_minus_beats', 'test_framepos_minus_beats', ['test/framepos_minus_beats_test.cc']) + create_ardour_test_program(bld, obj.includes, 'jack_utils', 'test_jack_utils', ['test/jack_utils_test.cc']) create_ardour_test_program(bld, obj.includes, 'playlist_equivalent_regions', 'test_playlist_equivalent_regions', ['test/playlist_equivalent_regions_test.cc']) create_ardour_test_program(bld, obj.includes, 'playlist_layering', 'test_playlist_layering', ['test/playlist_layering_test.cc']) create_ardour_test_program(bld, obj.includes, 'plugins_test', 'test_plugins', ['test/plugins_test.cc']) @@ -497,6 +506,7 @@ def build(bld): test/framewalk_to_beats_test.cc test/framepos_plus_beats_test.cc test/framepos_minus_beats_test.cc + test/jack_utils_test.cc test/playlist_equivalent_regions_test.cc test/playlist_layering_test.cc test/plugins_test.cc From 020ca43ed04c5effc00dea055d9c227627c6a8b7 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 12:53:16 -0400 Subject: [PATCH 59/69] add and Update mutex test that is no longer necessary now that glib has been fixed --- libs/pbd/test/mutex_test.cc | 24 ++++++++++++++++++++++++ libs/pbd/test/mutex_test.h | 17 +++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 libs/pbd/test/mutex_test.cc create mode 100644 libs/pbd/test/mutex_test.h diff --git a/libs/pbd/test/mutex_test.cc b/libs/pbd/test/mutex_test.cc new file mode 100644 index 0000000000..52c36c4695 --- /dev/null +++ b/libs/pbd/test/mutex_test.cc @@ -0,0 +1,24 @@ +#include "mutex_test.h" + +CPPUNIT_TEST_SUITE_REGISTRATION (MutexTest); + +using namespace std; + +MutexTest::MutexTest () +{ +} + +void +MutexTest::testBasic () +{ + Glib::Threads::Mutex::Lock lm (m_mutex); + + CPPUNIT_ASSERT (lm.locked()); + + /* This will fail on POSIX systems but not on some older versions of glib + * on win32 as TryEnterCriticalSection is used and it will return true + * as CriticalSection is reentrant and fail the assertion. + */ + CPPUNIT_ASSERT (!m_mutex.trylock()); + +} diff --git a/libs/pbd/test/mutex_test.h b/libs/pbd/test/mutex_test.h new file mode 100644 index 0000000000..95b6ea3f65 --- /dev/null +++ b/libs/pbd/test/mutex_test.h @@ -0,0 +1,17 @@ +#include +#include +#include "glibmm/threads.h" + +class MutexTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE (MutexTest); + CPPUNIT_TEST (testBasic); + CPPUNIT_TEST_SUITE_END (); + +public: + MutexTest (); + void testBasic (); + +private: + Glib::Threads::Mutex m_mutex; +}; From 94145732f3bd406ec75652117c02c8aaab6777ca Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:16:09 -0400 Subject: [PATCH 60/69] Build system changes to support mingw build target --- gtk2_ardour/wscript | 8 ++++++-- libs/ardour/wscript | 9 +++++---- libs/pbd/wscript | 6 ++++-- libs/surfaces/wscript | 2 +- libs/taglib/wscript | 1 + wscript | 39 ++++++++++++++++++++++++++++++++++----- 6 files changed, 51 insertions(+), 14 deletions(-) diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index bb4e2035ec..429b8c2dbd 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -266,8 +266,9 @@ def configure(conf): 'gtk2_ardour', conf.env['MAJOR'], conf.env['MINOR'], 0) autowaf.configure(conf) - if re.search ("linux", sys.platform) != None: - autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA') + if Options.options.dist_target == 'auto': + if re.search ("linux", sys.platform) != None: + autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA') # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present @@ -418,6 +419,9 @@ def build(bld): 'libardour_cp', 'libgtkmm2ext', 'libtaglib' ] + if bld.env['build_target'] == 'mingw': + if bld.env['DEBUG'] == False: + obj.linkflags = ['-mwindows'] if sys.platform == 'darwin': obj.use += ' libappleutility' obj.defines = [ diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 3afd4ce552..0ea3eee036 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -238,8 +238,6 @@ def configure(conf): path_prefix + 'version.cc', 'libardour3', conf.env['MAJOR'], conf.env['MINOR'], 0) autowaf.configure(conf) - autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', - atleast_version='0.3.2') autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.118.2') if Options.options.dist_target == 'auto': @@ -249,8 +247,11 @@ def configure(conf): autowaf.check_pkg(conf, 'portaudio-2.0', uselib_store='PORTAUDIO', atleast_version='19') autowaf.check_pkg(conf, 'libxml-2.0', uselib_store='XML') - autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', - atleast_version='0.4.0') + if Options.options.dist_target != 'mingw': + autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', + atleast_version='0.4.0') + autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', + atleast_version='0.3.2') autowaf.check_pkg(conf, 'samplerate', uselib_store='SAMPLERATE', atleast_version='0.1.0') autowaf.check_pkg(conf, 'sigc++-2.0', uselib_store='SIGCPP', diff --git a/libs/pbd/wscript b/libs/pbd/wscript index 2f93887e62..800b7d3be2 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -38,7 +38,6 @@ libpbd_sources = [ 'controllable.cc', 'controllable_descriptor.cc', 'clear_dir.cc', - 'crossthread.cc', 'cpus.cc', 'debug.cc', 'enumwriter.cc', @@ -122,6 +121,9 @@ def build(bld): if bld.is_defined('DEBUG_RT_ALLOC'): obj.source += 'debug_rt_alloc.c' + if bld.env['build_target'] != 'mingw': + obj.source += 'crossthread.cc' + obj.export_includes = ['.'] obj.includes = ['.'] obj.name = 'libpbd' @@ -156,7 +158,7 @@ def build(bld): testobj.uselib = 'CPPUNIT XML SNDFILE' testobj.use = 'libpbd' testobj.name = 'libpbd-tests' - if sys.platform != 'darwin': + if sys.platform != 'darwin' and bld.env['build_target'] != 'mingw': testobj.linkflags = ['-lrt'] diff --git a/libs/surfaces/wscript b/libs/surfaces/wscript index e0e91af725..1b2948c50a 100644 --- a/libs/surfaces/wscript +++ b/libs/surfaces/wscript @@ -43,7 +43,7 @@ def configure(conf): #if Options.options.tranzport and conf.is_defined('HAVE_USB'): # conf.define('BUILD_TRANZPORT', 1) - if conf.check_cc (header_name='poll.h', define_name='BUILD_MACKIE'): + if conf.check_cc (header_name='poll.h', define_name='BUILD_MACKIE', mandatory=False): sub_config_and_use(conf, 'mackie') if autowaf.check_pkg (conf, 'liblo', mandatory=False, uselib_store="LO", atleast_version="0.24"): diff --git a/libs/taglib/wscript b/libs/taglib/wscript index a6994d6391..8e6fbbbe48 100644 --- a/libs/taglib/wscript +++ b/libs/taglib/wscript @@ -65,6 +65,7 @@ def build(bld): '''.split() obj.export_includes = ['.', 'taglib', 'taglib/toolkit'] obj.includes = include_dirs + obj.defines = ['MAKE_TAGLIB_LIB'] obj.name = 'libtaglib' obj.target = 'taglib' obj.vnum = LIBTAGLIB_LIB_VERSION diff --git a/wscript b/wscript index a6106c0aef..a2f470ef03 100644 --- a/wscript +++ b/wscript @@ -32,7 +32,6 @@ children = [ 'libs/timecode', 'libs/ardour', 'libs/gtkmm2ext', - 'libs/clearlooks-newer', 'libs/audiographer', 'gtk2_ardour', 'export', @@ -114,7 +113,7 @@ def set_compiler_flags (conf,opt): debug_flags = [ '-pg' ] if opt.backtrace: - if platform != 'darwin' and not is_clang: + if platform != 'darwin' and not is_clang and opt.dist_target != 'mingw': debug_flags = [ '-rdynamic' ] # Autodetect @@ -390,7 +389,7 @@ def options(opt): opt.add_option('--depstack-root', type='string', default='~', dest='depstack_root', help='Directory/folder where dependency stack trees (gtk, a3) can be found (defaults to ~)') opt.add_option('--dist-target', type='string', default='auto', dest='dist_target', - help='Specify the target for cross-compiling [auto,none,x86,i386,i686,x86_64,powerpc,tiger,leopard]') + help='Specify the target for cross-compiling [auto,none,x86,i386,i686,x86_64,powerpc,tiger,leopard,mingw]') opt.add_option('--fpu-optimization', action='store_true', default=True, dest='fpu_optimization', help='Build runtime checked assembler code (default)') opt.add_option('--no-fpu-optimization', action='store_false', dest='fpu_optimization') @@ -410,7 +409,7 @@ def options(opt): help='Compile with support for LV2 (if Lilv+Suil is available)') opt.add_option('--no-lv2', action='store_false', dest='lv2', help='Do not compile with support for LV2') - opt.add_option('--lxvst', action='store_true', default=lxvst_default, dest='lxvst', + opt.add_option('--lxvst', action='store_true', default=False, dest='lxvst', help='Compile with support for linuxVST plugins') opt.add_option('--nls', action='store_true', default=True, dest='nls', help='Enable i18n (native language support) (default)') @@ -606,7 +605,21 @@ def configure(conf): autowaf.check_pkg(conf, 'libcurl', uselib_store='CURL', atleast_version='7.0.0') autowaf.check_pkg(conf, 'liblo', uselib_store='LO', atleast_version='0.26') - conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') + if Options.options.dist_target == 'mingw': + Options.options.fpu_optimization = False + conf.env.append_value('LIB', 'pthreadGC2') + # needed for at least libsmf + conf.check_cc(function_name='htonl', header_name='winsock2.h', lib='ws2_32') + conf.env.append_value('LIB', 'ws2_32') + # needed for mingw64 packages, not harmful on normal mingw build + conf.env.append_value('LIB', 'intl') + conf.check_cc(function_name='regcomp', header_name='regex.h', + lib='regex', uselib_store="REGEX", define_name='HAVE_REGEX_H') + # TODO put this only where it is needed + conf.env.append_value('LIB', 'regex') + + if Options.options.dist_target != 'mingw': + conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') # Tell everyone that this is a waf build @@ -659,6 +672,14 @@ def configure(conf): set_compiler_flags (conf, Options.options) + if sys.platform == 'darwin': + sub_config_and_use(conf, 'libs/appleutility') + elif Options.options.dist_target != 'mingw': + sub_config_and_use(conf, 'tools/sanity_check') + + if Options.options.dist_target != 'mingw': + sub_config_and_use(conf, 'libs/clearlooks-newer') + for i in children: sub_config_and_use(conf, i) @@ -742,6 +763,14 @@ def build(bld): autowaf.set_recursive() + if sys.platform == 'darwin': + bld.recurse('libs/appleutility') + elif bld.env['build_target'] != 'mingw': + bld.recurse('tools/sanity_check') + + if bld.env['build_target'] != 'mingw': + bld.recurse('libs/clearlooks-newer') + for i in children: bld.recurse(i) From fa09121a7f20ba424df5b9542564a467af63dc7a Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:17:32 -0400 Subject: [PATCH 61/69] tweaks to mingw build environment --- tools/windows_packaging/mingw-env.sh | 4 ++-- wscript | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/windows_packaging/mingw-env.sh b/tools/windows_packaging/mingw-env.sh index c6747ae03b..37a575885f 100644 --- a/tools/windows_packaging/mingw-env.sh +++ b/tools/windows_packaging/mingw-env.sh @@ -5,12 +5,12 @@ BASE=$(dirname $BASE) # up one BASE=$(dirname $BASE) # up one more BASE=$(dirname $BASE) # up one more -HOST=i686-pc-mingw32 +HOST=i686-w64-mingw32 MINGW_ROOT=/usr/$HOST/sys-root/mingw export PKG_CONFIG_PREFIX=$MINGW_ROOT export PKG_CONFIG_LIBDIR=$MINGW_ROOT/lib/pkgconfig -export PKGCONFIG=mingw32-pkg-config +export PKGCONFIG=pkg-config export AR=$HOST-ar export RANLIB=$HOST-ranlib export CC=$HOST-gcc diff --git a/wscript b/wscript index a2f470ef03..044e56d12c 100644 --- a/wscript +++ b/wscript @@ -590,13 +590,6 @@ def configure(conf): autowaf.check_header(conf, 'cxx', 'jack/session.h', define="JACK_SESSION", mandatory = False) - conf.check_cxx(fragment = "#include \nint main(void) { return (BOOST_VERSION >= 103900 ? 0 : 1); }\n", - execute = "1", - mandatory = True, - msg = 'Checking for boost library >= 1.39', - okmsg = 'ok', - errmsg = 'too old\nPlease install boost version 1.39 or higher.') - autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB', atleast_version='2.2') autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD', atleast_version='2.2') autowaf.check_pkg(conf, 'glibmm-2.4', uselib_store='GLIBMM', atleast_version='2.32.0') @@ -621,6 +614,13 @@ def configure(conf): if Options.options.dist_target != 'mingw': conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') + conf.check_cxx(fragment = "#include \nint main(void) { return (BOOST_VERSION >= 103900 ? 0 : 1); }\n", + execute = "1", + mandatory = True, + msg = 'Checking for boost library >= 1.39', + okmsg = 'ok', + errmsg = 'too old\nPlease install boost version 1.39 or higher.') + # Tell everyone that this is a waf build conf.env.append_value('CFLAGS', '-DWAF_BUILD') From 555174d510685a2ea2316f12c635c94f3f327370 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:20:48 -0400 Subject: [PATCH 62/69] Revert "tweaks to mingw build environment" This reverts commit fa09121a7f20ba424df5b9542564a467af63dc7a. --- tools/windows_packaging/mingw-env.sh | 4 ++-- wscript | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/windows_packaging/mingw-env.sh b/tools/windows_packaging/mingw-env.sh index 37a575885f..c6747ae03b 100644 --- a/tools/windows_packaging/mingw-env.sh +++ b/tools/windows_packaging/mingw-env.sh @@ -5,12 +5,12 @@ BASE=$(dirname $BASE) # up one BASE=$(dirname $BASE) # up one more BASE=$(dirname $BASE) # up one more -HOST=i686-w64-mingw32 +HOST=i686-pc-mingw32 MINGW_ROOT=/usr/$HOST/sys-root/mingw export PKG_CONFIG_PREFIX=$MINGW_ROOT export PKG_CONFIG_LIBDIR=$MINGW_ROOT/lib/pkgconfig -export PKGCONFIG=pkg-config +export PKGCONFIG=mingw32-pkg-config export AR=$HOST-ar export RANLIB=$HOST-ranlib export CC=$HOST-gcc diff --git a/wscript b/wscript index 044e56d12c..a2f470ef03 100644 --- a/wscript +++ b/wscript @@ -590,6 +590,13 @@ def configure(conf): autowaf.check_header(conf, 'cxx', 'jack/session.h', define="JACK_SESSION", mandatory = False) + conf.check_cxx(fragment = "#include \nint main(void) { return (BOOST_VERSION >= 103900 ? 0 : 1); }\n", + execute = "1", + mandatory = True, + msg = 'Checking for boost library >= 1.39', + okmsg = 'ok', + errmsg = 'too old\nPlease install boost version 1.39 or higher.') + autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB', atleast_version='2.2') autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD', atleast_version='2.2') autowaf.check_pkg(conf, 'glibmm-2.4', uselib_store='GLIBMM', atleast_version='2.32.0') @@ -614,13 +621,6 @@ def configure(conf): if Options.options.dist_target != 'mingw': conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') - conf.check_cxx(fragment = "#include \nint main(void) { return (BOOST_VERSION >= 103900 ? 0 : 1); }\n", - execute = "1", - mandatory = True, - msg = 'Checking for boost library >= 1.39', - okmsg = 'ok', - errmsg = 'too old\nPlease install boost version 1.39 or higher.') - # Tell everyone that this is a waf build conf.env.append_value('CFLAGS', '-DWAF_BUILD') From 96ea407d1a308373fe3f375485fe4af2065419c0 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:21:22 -0400 Subject: [PATCH 63/69] Revert "Build system changes to support mingw build target" This reverts commit 94145732f3bd406ec75652117c02c8aaab6777ca. --- gtk2_ardour/wscript | 8 ++------ libs/ardour/wscript | 9 ++++----- libs/pbd/wscript | 6 ++---- libs/surfaces/wscript | 2 +- libs/taglib/wscript | 1 - wscript | 39 +++++---------------------------------- 6 files changed, 14 insertions(+), 51 deletions(-) diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 429b8c2dbd..bb4e2035ec 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -266,9 +266,8 @@ def configure(conf): 'gtk2_ardour', conf.env['MAJOR'], conf.env['MINOR'], 0) autowaf.configure(conf) - if Options.options.dist_target == 'auto': - if re.search ("linux", sys.platform) != None: - autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA') + if re.search ("linux", sys.platform) != None: + autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA') # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present @@ -419,9 +418,6 @@ def build(bld): 'libardour_cp', 'libgtkmm2ext', 'libtaglib' ] - if bld.env['build_target'] == 'mingw': - if bld.env['DEBUG'] == False: - obj.linkflags = ['-mwindows'] if sys.platform == 'darwin': obj.use += ' libappleutility' obj.defines = [ diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 0ea3eee036..3afd4ce552 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -238,6 +238,8 @@ def configure(conf): path_prefix + 'version.cc', 'libardour3', conf.env['MAJOR'], conf.env['MINOR'], 0) autowaf.configure(conf) + autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', + atleast_version='0.3.2') autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.118.2') if Options.options.dist_target == 'auto': @@ -247,11 +249,8 @@ def configure(conf): autowaf.check_pkg(conf, 'portaudio-2.0', uselib_store='PORTAUDIO', atleast_version='19') autowaf.check_pkg(conf, 'libxml-2.0', uselib_store='XML') - if Options.options.dist_target != 'mingw': - autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', - atleast_version='0.4.0') - autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', - atleast_version='0.3.2') + autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', + atleast_version='0.4.0') autowaf.check_pkg(conf, 'samplerate', uselib_store='SAMPLERATE', atleast_version='0.1.0') autowaf.check_pkg(conf, 'sigc++-2.0', uselib_store='SIGCPP', diff --git a/libs/pbd/wscript b/libs/pbd/wscript index 800b7d3be2..2f93887e62 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -38,6 +38,7 @@ libpbd_sources = [ 'controllable.cc', 'controllable_descriptor.cc', 'clear_dir.cc', + 'crossthread.cc', 'cpus.cc', 'debug.cc', 'enumwriter.cc', @@ -121,9 +122,6 @@ def build(bld): if bld.is_defined('DEBUG_RT_ALLOC'): obj.source += 'debug_rt_alloc.c' - if bld.env['build_target'] != 'mingw': - obj.source += 'crossthread.cc' - obj.export_includes = ['.'] obj.includes = ['.'] obj.name = 'libpbd' @@ -158,7 +156,7 @@ def build(bld): testobj.uselib = 'CPPUNIT XML SNDFILE' testobj.use = 'libpbd' testobj.name = 'libpbd-tests' - if sys.platform != 'darwin' and bld.env['build_target'] != 'mingw': + if sys.platform != 'darwin': testobj.linkflags = ['-lrt'] diff --git a/libs/surfaces/wscript b/libs/surfaces/wscript index 1b2948c50a..e0e91af725 100644 --- a/libs/surfaces/wscript +++ b/libs/surfaces/wscript @@ -43,7 +43,7 @@ def configure(conf): #if Options.options.tranzport and conf.is_defined('HAVE_USB'): # conf.define('BUILD_TRANZPORT', 1) - if conf.check_cc (header_name='poll.h', define_name='BUILD_MACKIE', mandatory=False): + if conf.check_cc (header_name='poll.h', define_name='BUILD_MACKIE'): sub_config_and_use(conf, 'mackie') if autowaf.check_pkg (conf, 'liblo', mandatory=False, uselib_store="LO", atleast_version="0.24"): diff --git a/libs/taglib/wscript b/libs/taglib/wscript index 8e6fbbbe48..a6994d6391 100644 --- a/libs/taglib/wscript +++ b/libs/taglib/wscript @@ -65,7 +65,6 @@ def build(bld): '''.split() obj.export_includes = ['.', 'taglib', 'taglib/toolkit'] obj.includes = include_dirs - obj.defines = ['MAKE_TAGLIB_LIB'] obj.name = 'libtaglib' obj.target = 'taglib' obj.vnum = LIBTAGLIB_LIB_VERSION diff --git a/wscript b/wscript index a2f470ef03..a6106c0aef 100644 --- a/wscript +++ b/wscript @@ -32,6 +32,7 @@ children = [ 'libs/timecode', 'libs/ardour', 'libs/gtkmm2ext', + 'libs/clearlooks-newer', 'libs/audiographer', 'gtk2_ardour', 'export', @@ -113,7 +114,7 @@ def set_compiler_flags (conf,opt): debug_flags = [ '-pg' ] if opt.backtrace: - if platform != 'darwin' and not is_clang and opt.dist_target != 'mingw': + if platform != 'darwin' and not is_clang: debug_flags = [ '-rdynamic' ] # Autodetect @@ -389,7 +390,7 @@ def options(opt): opt.add_option('--depstack-root', type='string', default='~', dest='depstack_root', help='Directory/folder where dependency stack trees (gtk, a3) can be found (defaults to ~)') opt.add_option('--dist-target', type='string', default='auto', dest='dist_target', - help='Specify the target for cross-compiling [auto,none,x86,i386,i686,x86_64,powerpc,tiger,leopard,mingw]') + help='Specify the target for cross-compiling [auto,none,x86,i386,i686,x86_64,powerpc,tiger,leopard]') opt.add_option('--fpu-optimization', action='store_true', default=True, dest='fpu_optimization', help='Build runtime checked assembler code (default)') opt.add_option('--no-fpu-optimization', action='store_false', dest='fpu_optimization') @@ -409,7 +410,7 @@ def options(opt): help='Compile with support for LV2 (if Lilv+Suil is available)') opt.add_option('--no-lv2', action='store_false', dest='lv2', help='Do not compile with support for LV2') - opt.add_option('--lxvst', action='store_true', default=False, dest='lxvst', + opt.add_option('--lxvst', action='store_true', default=lxvst_default, dest='lxvst', help='Compile with support for linuxVST plugins') opt.add_option('--nls', action='store_true', default=True, dest='nls', help='Enable i18n (native language support) (default)') @@ -605,21 +606,7 @@ def configure(conf): autowaf.check_pkg(conf, 'libcurl', uselib_store='CURL', atleast_version='7.0.0') autowaf.check_pkg(conf, 'liblo', uselib_store='LO', atleast_version='0.26') - if Options.options.dist_target == 'mingw': - Options.options.fpu_optimization = False - conf.env.append_value('LIB', 'pthreadGC2') - # needed for at least libsmf - conf.check_cc(function_name='htonl', header_name='winsock2.h', lib='ws2_32') - conf.env.append_value('LIB', 'ws2_32') - # needed for mingw64 packages, not harmful on normal mingw build - conf.env.append_value('LIB', 'intl') - conf.check_cc(function_name='regcomp', header_name='regex.h', - lib='regex', uselib_store="REGEX", define_name='HAVE_REGEX_H') - # TODO put this only where it is needed - conf.env.append_value('LIB', 'regex') - - if Options.options.dist_target != 'mingw': - conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') + conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') # Tell everyone that this is a waf build @@ -672,14 +659,6 @@ def configure(conf): set_compiler_flags (conf, Options.options) - if sys.platform == 'darwin': - sub_config_and_use(conf, 'libs/appleutility') - elif Options.options.dist_target != 'mingw': - sub_config_and_use(conf, 'tools/sanity_check') - - if Options.options.dist_target != 'mingw': - sub_config_and_use(conf, 'libs/clearlooks-newer') - for i in children: sub_config_and_use(conf, i) @@ -763,14 +742,6 @@ def build(bld): autowaf.set_recursive() - if sys.platform == 'darwin': - bld.recurse('libs/appleutility') - elif bld.env['build_target'] != 'mingw': - bld.recurse('tools/sanity_check') - - if bld.env['build_target'] != 'mingw': - bld.recurse('libs/clearlooks-newer') - for i in children: bld.recurse(i) From 00ae5492f400c2a6662467c355066cfbffdcb29f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:43:17 -0400 Subject: [PATCH 64/69] (reapply with fixes) Build system changes to support mingw build target --- gtk2_ardour/wscript | 8 ++++++-- libs/ardour/wscript | 9 +++++---- libs/pbd/wscript | 6 ++++-- libs/surfaces/wscript | 2 +- libs/taglib/wscript | 1 + wscript | 37 +++++++++++++++++++++++++++++++++---- 6 files changed, 50 insertions(+), 13 deletions(-) diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index bb4e2035ec..429b8c2dbd 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -266,8 +266,9 @@ def configure(conf): 'gtk2_ardour', conf.env['MAJOR'], conf.env['MINOR'], 0) autowaf.configure(conf) - if re.search ("linux", sys.platform) != None: - autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA') + if Options.options.dist_target == 'auto': + if re.search ("linux", sys.platform) != None: + autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA') # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present @@ -418,6 +419,9 @@ def build(bld): 'libardour_cp', 'libgtkmm2ext', 'libtaglib' ] + if bld.env['build_target'] == 'mingw': + if bld.env['DEBUG'] == False: + obj.linkflags = ['-mwindows'] if sys.platform == 'darwin': obj.use += ' libappleutility' obj.defines = [ diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 3afd4ce552..5e8b27d4ea 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -238,8 +238,6 @@ def configure(conf): path_prefix + 'version.cc', 'libardour3', conf.env['MAJOR'], conf.env['MINOR'], 0) autowaf.configure(conf) - autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', - atleast_version='0.3.2') autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.118.2') if Options.options.dist_target == 'auto': @@ -249,8 +247,11 @@ def configure(conf): autowaf.check_pkg(conf, 'portaudio-2.0', uselib_store='PORTAUDIO', atleast_version='19') autowaf.check_pkg(conf, 'libxml-2.0', uselib_store='XML') - autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', - atleast_version='0.4.0') + if Options.options.dist_target != 'mingw': + autowaf.check_pkg(conf, 'lrdf', uselib_store='LRDF', + atleast_version='0.4.0') + autowaf.check_pkg(conf, 'aubio', uselib_store='AUBIO', + atleast_version='0.3.2') autowaf.check_pkg(conf, 'samplerate', uselib_store='SAMPLERATE', atleast_version='0.1.0') autowaf.check_pkg(conf, 'sigc++-2.0', uselib_store='SIGCPP', diff --git a/libs/pbd/wscript b/libs/pbd/wscript index 2f93887e62..91d9b2c50b 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -38,7 +38,6 @@ libpbd_sources = [ 'controllable.cc', 'controllable_descriptor.cc', 'clear_dir.cc', - 'crossthread.cc', 'cpus.cc', 'debug.cc', 'enumwriter.cc', @@ -122,6 +121,9 @@ def build(bld): if bld.is_defined('DEBUG_RT_ALLOC'): obj.source += 'debug_rt_alloc.c' + if bld.env['build_target'] != 'mingw': + obj.source += [ 'crossthread.cc' ] + obj.export_includes = ['.'] obj.includes = ['.'] obj.name = 'libpbd' @@ -156,7 +158,7 @@ def build(bld): testobj.uselib = 'CPPUNIT XML SNDFILE' testobj.use = 'libpbd' testobj.name = 'libpbd-tests' - if sys.platform != 'darwin': + if sys.platform != 'darwin' and bld.env['build_target'] != 'mingw': testobj.linkflags = ['-lrt'] diff --git a/libs/surfaces/wscript b/libs/surfaces/wscript index e0e91af725..1b2948c50a 100644 --- a/libs/surfaces/wscript +++ b/libs/surfaces/wscript @@ -43,7 +43,7 @@ def configure(conf): #if Options.options.tranzport and conf.is_defined('HAVE_USB'): # conf.define('BUILD_TRANZPORT', 1) - if conf.check_cc (header_name='poll.h', define_name='BUILD_MACKIE'): + if conf.check_cc (header_name='poll.h', define_name='BUILD_MACKIE', mandatory=False): sub_config_and_use(conf, 'mackie') if autowaf.check_pkg (conf, 'liblo', mandatory=False, uselib_store="LO", atleast_version="0.24"): diff --git a/libs/taglib/wscript b/libs/taglib/wscript index a6994d6391..8e6fbbbe48 100644 --- a/libs/taglib/wscript +++ b/libs/taglib/wscript @@ -65,6 +65,7 @@ def build(bld): '''.split() obj.export_includes = ['.', 'taglib', 'taglib/toolkit'] obj.includes = include_dirs + obj.defines = ['MAKE_TAGLIB_LIB'] obj.name = 'libtaglib' obj.target = 'taglib' obj.vnum = LIBTAGLIB_LIB_VERSION diff --git a/wscript b/wscript index a6106c0aef..8599b41148 100644 --- a/wscript +++ b/wscript @@ -32,7 +32,6 @@ children = [ 'libs/timecode', 'libs/ardour', 'libs/gtkmm2ext', - 'libs/clearlooks-newer', 'libs/audiographer', 'gtk2_ardour', 'export', @@ -390,7 +389,7 @@ def options(opt): opt.add_option('--depstack-root', type='string', default='~', dest='depstack_root', help='Directory/folder where dependency stack trees (gtk, a3) can be found (defaults to ~)') opt.add_option('--dist-target', type='string', default='auto', dest='dist_target', - help='Specify the target for cross-compiling [auto,none,x86,i386,i686,x86_64,powerpc,tiger,leopard]') + help='Specify the target for cross-compiling [auto,none,x86,i386,i686,x86_64,powerpc,tiger,leopard,mingw]') opt.add_option('--fpu-optimization', action='store_true', default=True, dest='fpu_optimization', help='Build runtime checked assembler code (default)') opt.add_option('--no-fpu-optimization', action='store_false', dest='fpu_optimization') @@ -410,7 +409,7 @@ def options(opt): help='Compile with support for LV2 (if Lilv+Suil is available)') opt.add_option('--no-lv2', action='store_false', dest='lv2', help='Do not compile with support for LV2') - opt.add_option('--lxvst', action='store_true', default=lxvst_default, dest='lxvst', + opt.add_option('--lxvst', action='store_true', default=False, dest='lxvst', help='Compile with support for linuxVST plugins') opt.add_option('--nls', action='store_true', default=True, dest='nls', help='Enable i18n (native language support) (default)') @@ -606,7 +605,21 @@ def configure(conf): autowaf.check_pkg(conf, 'libcurl', uselib_store='CURL', atleast_version='7.0.0') autowaf.check_pkg(conf, 'liblo', uselib_store='LO', atleast_version='0.26') - conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') + if Options.options.dist_target == 'mingw': + Options.options.fpu_optimization = False + conf.env.append_value('LIB', 'pthreadGC2') + # needed for at least libsmf + conf.check_cc(function_name='htonl', header_name='winsock2.h', lib='ws2_32') + conf.env.append_value('LIB', 'ws2_32') + # needed for mingw64 packages, not harmful on normal mingw build + conf.env.append_value('LIB', 'intl') + conf.check_cc(function_name='regcomp', header_name='regex.h', + lib='regex', uselib_store="REGEX", define_name='HAVE_REGEX_H') + # TODO put this only where it is needed + conf.env.append_value('LIB', 'regex') + + if Options.options.dist_target != 'mingw': + conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') # Tell everyone that this is a waf build @@ -659,6 +672,14 @@ def configure(conf): set_compiler_flags (conf, Options.options) + if sys.platform == 'darwin': + sub_config_and_use(conf, 'libs/appleutility') + elif Options.options.dist_target != 'mingw': + sub_config_and_use(conf, 'tools/sanity_check') + + if Options.options.dist_target != 'mingw': + sub_config_and_use(conf, 'libs/clearlooks-newer') + for i in children: sub_config_and_use(conf, i) @@ -742,6 +763,14 @@ def build(bld): autowaf.set_recursive() + if sys.platform == 'darwin': + bld.recurse('libs/appleutility') + elif bld.env['build_target'] != 'mingw': + bld.recurse('tools/sanity_check') + + if bld.env['build_target'] != 'mingw': + bld.recurse('libs/clearlooks-newer') + for i in children: bld.recurse(i) From 590e1fb45834caecd31cd1b668a2f7045edae40e Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:43:47 -0400 Subject: [PATCH 65/69] Disable check for boost with mingw build --- wscript | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/wscript b/wscript index 8599b41148..148b843a61 100644 --- a/wscript +++ b/wscript @@ -590,13 +590,6 @@ def configure(conf): autowaf.check_header(conf, 'cxx', 'jack/session.h', define="JACK_SESSION", mandatory = False) - conf.check_cxx(fragment = "#include \nint main(void) { return (BOOST_VERSION >= 103900 ? 0 : 1); }\n", - execute = "1", - mandatory = True, - msg = 'Checking for boost library >= 1.39', - okmsg = 'ok', - errmsg = 'too old\nPlease install boost version 1.39 or higher.') - autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB', atleast_version='2.2') autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD', atleast_version='2.2') autowaf.check_pkg(conf, 'glibmm-2.4', uselib_store='GLIBMM', atleast_version='2.32.0') @@ -621,6 +614,13 @@ def configure(conf): if Options.options.dist_target != 'mingw': conf.check_cc(function_name='dlopen', header_name='dlfcn.h', lib='dl', uselib_store='DL') + conf.check_cxx(fragment = "#include \nint main(void) { return (BOOST_VERSION >= 103900 ? 0 : 1); }\n", + execute = "1", + mandatory = True, + msg = 'Checking for boost library >= 1.39', + okmsg = 'ok', + errmsg = 'too old\nPlease install boost version 1.39 or higher.') + # Tell everyone that this is a waf build conf.env.append_value('CFLAGS', '-DWAF_BUILD') From a2a7545ea18dc2318163e8588e8da3ab7d68b373 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:44:11 -0400 Subject: [PATCH 66/69] Update mingw environment to work with mingw-64 toolchain on F17 --- tools/windows_packaging/mingw-env.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/windows_packaging/mingw-env.sh b/tools/windows_packaging/mingw-env.sh index c6747ae03b..37a575885f 100644 --- a/tools/windows_packaging/mingw-env.sh +++ b/tools/windows_packaging/mingw-env.sh @@ -5,12 +5,12 @@ BASE=$(dirname $BASE) # up one BASE=$(dirname $BASE) # up one more BASE=$(dirname $BASE) # up one more -HOST=i686-pc-mingw32 +HOST=i686-w64-mingw32 MINGW_ROOT=/usr/$HOST/sys-root/mingw export PKG_CONFIG_PREFIX=$MINGW_ROOT export PKG_CONFIG_LIBDIR=$MINGW_ROOT/lib/pkgconfig -export PKGCONFIG=mingw32-pkg-config +export PKGCONFIG=pkg-config export AR=$HOST-ar export RANLIB=$HOST-ranlib export CC=$HOST-gcc From 9b8a3a1ea46533819e17d02a39aaf84794d86db3 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:45:00 -0400 Subject: [PATCH 67/69] Update mingw package script for Fedora 17 --- tools/windows_packaging/package.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/windows_packaging/package.sh b/tools/windows_packaging/package.sh index 2d7cb7d097..1270bc0cc5 100644 --- a/tools/windows_packaging/package.sh +++ b/tools/windows_packaging/package.sh @@ -96,7 +96,7 @@ libFLAC-8.dll libogg-0.dll libvorbis-0.dll libvorbisenc-2.dll -libffi-5.dll +libffi-6.dll libidn-11.dll libintl-8.dll libpango-1.0-0.dll @@ -105,7 +105,7 @@ libpangoft2-1.0-0.dll libpangomm-1.4-1.dll libpangowin32-1.0-0.dll libpixman-1-0.dll -libpng14-14.dll +libpng15-15.dll libsamplerate-0.dll libsigc-2.0-0.dll libsndfile-1.dll From f9549b6c5c56bc664a987c74d4491a143db6c4d6 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 13:45:36 -0400 Subject: [PATCH 68/69] Update Pango modules file to work with Pango version in Fedora 17 --- tools/windows_packaging/pango.modules | 60 +++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/tools/windows_packaging/pango.modules b/tools/windows_packaging/pango.modules index 70d300bc10..115c6a5fd8 100644 --- a/tools/windows_packaging/pango.modules +++ b/tools/windows_packaging/pango.modules @@ -3,33 +3,33 @@ # # ModulesPath = Z:\usr\i686-pc-mingw32\sys-root\mingw\lib\pango\1.6.0\modules # -"lib\\pango\\1.6.0\\modules\\pango-thai-fc.dll" ThaiScriptEngineFc PangoEngineShape PangoRenderFc thai:* lao:* -"lib\\pango\\1.6.0\\modules\\pango-basic-win32.dll" BasicScriptEngineWin32 PangoEngineShape PangoRenderWin32 common: -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" devaScriptEngineFc PangoEngineShape PangoRenderFc devanagari:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" bengScriptEngineFc PangoEngineShape PangoRenderFc bengali:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" guruScriptEngineFc PangoEngineShape PangoRenderFc gurmukhi:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" gujrScriptEngineFc PangoEngineShape PangoRenderFc gujarati:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" oryaScriptEngineFc PangoEngineShape PangoRenderFc oriya:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" tamlScriptEngineFc PangoEngineShape PangoRenderFc tamil:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" teluScriptEngineFc PangoEngineShape PangoRenderFc telugu:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" kndaScriptEngineFc PangoEngineShape PangoRenderFc kannada:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" mlymScriptEngineFc PangoEngineShape PangoRenderFc malayalam:* -"lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" sinhScriptEngineFc PangoEngineShape PangoRenderFc sinhala:* -"lib\\pango\\1.6.0\\modules\\pango-syriac-fc.dll" SyriacScriptEngineFc PangoEngineShape PangoRenderFc syriac:* -"lib\\pango\\1.6.0\\modules\\pango-khmer-fc.dll" KhmerScriptEngineFc PangoEngineShape PangoRenderFc khmer:* -"lib\\pango\\1.6.0\\modules\\pango-arabic-lang.dll" ArabicScriptEngineLang PangoEngineLang PangoRenderNone arabic:* -"lib\\pango\\1.6.0\\modules\\pango-basic-fc.dll" BasicScriptEngineFc PangoEngineShape PangoRenderFc latin:* cyrillic:* greek:* armenian:* georgian:* runic:* ogham:* bopomofo:* cherokee:* coptic:* deseret:* ethiopic:* gothic:* han:* hiragana:* katakana:* old-italic:* canadian-aboriginal:* yi:* braille:* cypriot:* limbu:* osmanya:* shavian:* linear-b:* ugaritic:* glagolitic:* cuneiform:* phoenician:* common: -"lib\\pango\\1.6.0\\modules\\pango-arabic-fc.dll" ArabicScriptEngineFc PangoEngineShape PangoRenderFc arabic:* nko:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" devaIndicScriptEngineLang PangoEngineLang PangoRenderNone devanagari:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" bengIndicScriptEngineLang PangoEngineLang PangoRenderNone bengali:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" guruIndicScriptEngineLang PangoEngineLang PangoRenderNone gurmukhi:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" gujrIndicScriptEngineLang PangoEngineLang PangoRenderNone gujarati:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" oryaIndicScriptEngineLang PangoEngineLang PangoRenderNone oriya:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" tamlIndicScriptEngineLang PangoEngineLang PangoRenderNone tamil:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" teluIndicScriptEngineLang PangoEngineLang PangoRenderNone telugu:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" kndaIndicScriptEngineLang PangoEngineLang PangoRenderNone kannada:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" mlymIndicScriptEngineLang PangoEngineLang PangoRenderNone malayalam:* -"lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" sinhIndicScriptEngineLang PangoEngineLang PangoRenderNone sinhala:* -"lib\\pango\\1.6.0\\modules\\pango-hebrew-fc.dll" HebrewScriptEngineFc PangoEngineShape PangoRenderFc hebrew:* -"lib\\pango\\1.6.0\\modules\\pango-tibetan-fc.dll" TibetanScriptEngineFc PangoEngineShape PangoRenderFc tibetan:* -"lib\\pango\\1.6.0\\modules\\pango-hangul-fc.dll" HangulScriptEngineFc PangoEngineShape PangoRenderFc hangul:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-thai-fc.dll" ThaiScriptEngineFc PangoEngineShape PangoRenderFc thai:* lao:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-basic-win32.dll" BasicScriptEngineWin32 PangoEngineShape PangoRenderWin32 common: +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" devaScriptEngineFc PangoEngineShape PangoRenderFc devanagari:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" bengScriptEngineFc PangoEngineShape PangoRenderFc bengali:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" guruScriptEngineFc PangoEngineShape PangoRenderFc gurmukhi:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" gujrScriptEngineFc PangoEngineShape PangoRenderFc gujarati:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" oryaScriptEngineFc PangoEngineShape PangoRenderFc oriya:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" tamlScriptEngineFc PangoEngineShape PangoRenderFc tamil:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" teluScriptEngineFc PangoEngineShape PangoRenderFc telugu:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" kndaScriptEngineFc PangoEngineShape PangoRenderFc kannada:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" mlymScriptEngineFc PangoEngineShape PangoRenderFc malayalam:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-fc.dll" sinhScriptEngineFc PangoEngineShape PangoRenderFc sinhala:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-syriac-fc.dll" SyriacScriptEngineFc PangoEngineShape PangoRenderFc syriac:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-khmer-fc.dll" KhmerScriptEngineFc PangoEngineShape PangoRenderFc khmer:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-arabic-lang.dll" ArabicScriptEngineLang PangoEngineLang PangoRenderNone arabic:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-basic-fc.dll" BasicScriptEngineFc PangoEngineShape PangoRenderFc latin:* cyrillic:* greek:* armenian:* georgian:* runic:* ogham:* bopomofo:* cherokee:* coptic:* deseret:* ethiopic:* gothic:* han:* hiragana:* katakana:* old-italic:* canadian-aboriginal:* yi:* braille:* cypriot:* limbu:* osmanya:* shavian:* linear-b:* ugaritic:* glagolitic:* cuneiform:* phoenician:* common: +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-arabic-fc.dll" ArabicScriptEngineFc PangoEngineShape PangoRenderFc arabic:* nko:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" devaIndicScriptEngineLang PangoEngineLang PangoRenderNone devanagari:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" bengIndicScriptEngineLang PangoEngineLang PangoRenderNone bengali:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" guruIndicScriptEngineLang PangoEngineLang PangoRenderNone gurmukhi:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" gujrIndicScriptEngineLang PangoEngineLang PangoRenderNone gujarati:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" oryaIndicScriptEngineLang PangoEngineLang PangoRenderNone oriya:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" tamlIndicScriptEngineLang PangoEngineLang PangoRenderNone tamil:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" teluIndicScriptEngineLang PangoEngineLang PangoRenderNone telugu:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" kndaIndicScriptEngineLang PangoEngineLang PangoRenderNone kannada:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" mlymIndicScriptEngineLang PangoEngineLang PangoRenderNone malayalam:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-indic-lang.dll" sinhIndicScriptEngineLang PangoEngineLang PangoRenderNone sinhala:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-hebrew-fc.dll" HebrewScriptEngineFc PangoEngineShape PangoRenderFc hebrew:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-tibetan-fc.dll" TibetanScriptEngineFc PangoEngineShape PangoRenderFc tibetan:* +"..\\..\\lib\\pango\\1.6.0\\modules\\pango-hangul-fc.dll" HangulScriptEngineFc PangoEngineShape PangoRenderFc hangul:* From 15be15451592817731a271cd16d9b94c40c3023b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 14:29:00 -0400 Subject: [PATCH 69/69] use g_unlink() rather than unlink() universally, requires in several files --- gtk2_ardour/editor_export_audio.cc | 6 ++++-- gtk2_ardour/editor_videotimeline.cc | 4 +++- gtk2_ardour/export_video_dialog.cc | 16 +++++++++------- gtk2_ardour/sfdb_ui.cc | 4 +++- gtk2_ardour/transcode_video_dialog.cc | 6 ++++-- libs/ardour/audio_unit.cc | 2 +- libs/ardour/audiofilesource.cc | 7 ++++--- libs/ardour/audiosource.cc | 2 +- libs/ardour/export_handler.cc | 5 +++-- libs/ardour/import.cc | 3 ++- libs/ardour/lv2_plugin.cc | 3 ++- libs/ardour/session_state.cc | 2 +- libs/ardour/smf_source.cc | 3 ++- libs/gtkmm2ext/bindings.cc | 4 +++- libs/gtkmm2ext/motionfeedback.cc | 8 +++++--- libs/pbd/clear_dir.cc | 3 ++- .../surfaces/frontier/kernel_drivers/tranzport.c | 2 +- libs/surfaces/osc/osc.cc | 7 ++++--- 18 files changed, 54 insertions(+), 33 deletions(-) diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index 877a39e773..e40030d671 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -25,6 +25,8 @@ #include +#include + #include "gtkmm2ext/choice.h" #include "pbd/pthread_utils.h" @@ -158,11 +160,11 @@ Editor::export_region () switch (ret) { case Gtk::RESPONSE_ACCEPT: - /* force unlink because the backend code will + /* force ::g_unlink because the backend code will go wrong if it tries to open an existing file for writing. */ - ::unlink (path.c_str()); + ::g_unlink (path.c_str()); break; default: return; diff --git a/gtk2_ardour/editor_videotimeline.cc b/gtk2_ardour/editor_videotimeline.cc index 7395d767c7..5da8a295b7 100644 --- a/gtk2_ardour/editor_videotimeline.cc +++ b/gtk2_ardour/editor_videotimeline.cc @@ -20,6 +20,8 @@ #include +#include + #include "ardour/profile.h" #include "ardour/rc_configuration.h" #include "ardour/audio_track.h" @@ -118,7 +120,7 @@ Editor::embed_audio_from_video (std::string path, framepos_t n) import_status.all_done = true; #endif - unlink(path.c_str()); + ::g_unlink(path.c_str()); } void diff --git a/gtk2_ardour/export_video_dialog.cc b/gtk2_ardour/export_video_dialog.cc index ce85fad81e..d51fd60e2b 100644 --- a/gtk2_ardour/export_video_dialog.cc +++ b/gtk2_ardour/export_video_dialog.cc @@ -30,6 +30,8 @@ #include #include +#include + #include "pbd/error.h" #include "pbd/convert.h" #include "gtkmm2ext/utils.h" @@ -405,8 +407,8 @@ void ExportVideoDialog::finished () { if (aborted) { - unlink(outfn_path_entry.get_text().c_str()); - unlink (insnd.c_str()); + ::g_unlink(outfn_path_entry.get_text().c_str()); + ::g_unlink (insnd.c_str()); Gtk::Dialog::response(RESPONSE_CANCEL); } else if (twopass && firstpass) { firstpass = false; @@ -416,9 +418,9 @@ ExportVideoDialog::finished () if (twopass_checkbox.get_active()) { std::string outfn = outfn_path_entry.get_text(); std::string p2log = Glib::path_get_dirname (outfn) + G_DIR_SEPARATOR + "ffmpeg2pass"; - unlink (p2log.c_str()); + ::g_unlink (p2log.c_str()); } - unlink (insnd.c_str()); + ::g_unlink (insnd.c_str()); Gtk::Dialog::response(RESPONSE_ACCEPT); } } @@ -554,7 +556,7 @@ ExportVideoDialog::launch_export () audio_progress_connection.disconnect(); status->finish (); if (status->aborted()) { - unlink (insnd.c_str()); + ::g_unlink (insnd.c_str()); Gtk::Dialog::response(RESPONSE_CANCEL); return; } @@ -571,14 +573,14 @@ ExportVideoDialog::encode_pass (int pass) transcoder = new TranscodeFfmpeg(invid); if (!transcoder->ffexec_ok()) { /* ffmpeg binary was not found. TranscodeFfmpeg prints a warning */ - unlink (insnd.c_str()); + ::g_unlink (insnd.c_str()); Gtk::Dialog::response(RESPONSE_CANCEL); return; } if (!transcoder->probe_ok()) { /* video input file can not be read */ warning << _("Export Video: Video input file cannot be read.") << endmsg; - unlink (insnd.c_str()); + ::g_unlink (insnd.c_str()); Gtk::Dialog::response(RESPONSE_CANCEL); return; } diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index 482a3b61b7..f116041d03 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -31,6 +31,8 @@ #include #include + +#include #include #include "pbd/convert.h" @@ -1487,7 +1489,7 @@ SoundFileOmega::check_link_status (const Session* s, const vector& paths goto out; } - unlink (tmpc); + ::g_unlink (tmpc); } ret = true; diff --git a/gtk2_ardour/transcode_video_dialog.cc b/gtk2_ardour/transcode_video_dialog.cc index fa5d447a3a..4d8b9b9f11 100644 --- a/gtk2_ardour/transcode_video_dialog.cc +++ b/gtk2_ardour/transcode_video_dialog.cc @@ -30,6 +30,8 @@ #include #include +#include + #include "pbd/error.h" #include "pbd/convert.h" #include "gtkmm2ext/utils.h" @@ -301,9 +303,9 @@ void TranscodeVideoDialog::finished () { if (aborted) { - unlink(path_entry.get_text().c_str()); + ::g_unlink(path_entry.get_text().c_str()); if (!audiofile.empty()) { - unlink(audiofile.c_str()); + ::g_unlink(audiofile.c_str()); } Gtk::Dialog::response(RESPONSE_CANCEL); } else { diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index 0e9a11e6df..ea2e93c5a0 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -2452,7 +2452,7 @@ AUPluginInfo::save_cached_info () if (!tree.write (path)) { error << string_compose (_("could not save AU cache to %1"), path) << endmsg; - unlink (path.c_str()); + ::g_unlink (path.c_str()); } } diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 13b03f8f48..014baa9031 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -40,6 +40,7 @@ #include +#include #include #include #include @@ -133,8 +134,8 @@ AudioFileSource::~AudioFileSource () { DEBUG_TRACE (DEBUG::Destruction, string_compose ("AudioFileSource destructor %1, removable? %2\n", _path, removable())); if (removable()) { - unlink (_path.c_str()); - unlink (peakpath.c_str()); + ::g_unlink (_path.c_str()); + ::g_unlink (peakpath.c_str()); } } @@ -292,7 +293,7 @@ AudioFileSource::mark_streaming_write_completed () int AudioFileSource::move_dependents_to_trash() { - return ::unlink (peakpath.c_str()); + return ::g_unlink (peakpath.c_str()); } void diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index d8c25b0200..e224186bd2 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -653,7 +653,7 @@ AudioSource::build_peaks_from_scratch () out: if (ret) { DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", peakpath)); - unlink (peakpath.c_str()); + ::g_unlink (peakpath.c_str()); } return ret; diff --git a/libs/ardour/export_handler.cc b/libs/ardour/export_handler.cc index 4a6b0552c5..5710ecc452 100644 --- a/libs/ardour/export_handler.cc +++ b/libs/ardour/export_handler.cc @@ -20,6 +20,7 @@ #include "ardour/export_handler.h" +#include #include #include @@ -415,10 +416,10 @@ ExportHandler::export_cd_marker_file (ExportTimespanPtr timespan, ExportFormatSp } catch (std::exception& e) { error << string_compose (_("an error occured while writing a TOC/CUE file: %1"), e.what()) << endmsg; - ::unlink (filepath.c_str()); + ::g_unlink (filepath.c_str()); } catch (Glib::Exception& e) { error << string_compose (_("an error occured while writing a TOC/CUE file: %1"), e.what()) << endmsg; - ::unlink (filepath.c_str()); + ::g_unlink (filepath.c_str()); } } diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index 48937fb576..9be72a9966 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -464,7 +465,7 @@ remove_file_source (boost::shared_ptr source) boost::shared_ptr fs = boost::dynamic_pointer_cast (source); if (fs) { - ::unlink (fs->path().c_str()); + ::g_unlink (fs->path().c_str()); } } diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index d49f8412b7..c5a02575fd 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -1085,7 +1086,7 @@ LV2Plugin::do_remove_preset(string name) name + ".ttl" ) ); - unlink(preset_file.c_str()); + ::g_unlink(preset_file.c_str()); } bool diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index de573e61b6..62edaa3911 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2900,7 +2900,7 @@ Session::cleanup_sources (CleanupReport& rep) string peakpath = peak_path (base); if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) { - if (::unlink (peakpath.c_str()) != 0) { + if (::g_unlink (peakpath.c_str()) != 0) { error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), peakpath, _path, strerror (errno)) << endmsg; diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 830fd75fdf..d915bba845 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -30,6 +30,7 @@ #include "pbd/stl_delete.h" #include "pbd/strsplit.h" +#include #include #include "evoral/Control.hpp" @@ -96,7 +97,7 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist) SMFSource::~SMFSource () { if (removable()) { - unlink (_path.c_str()); + ::g_unlink (_path.c_str()); } } diff --git a/libs/gtkmm2ext/bindings.cc b/libs/gtkmm2ext/bindings.cc index e049cd8d57..f96bd586d9 100644 --- a/libs/gtkmm2ext/bindings.cc +++ b/libs/gtkmm2ext/bindings.cc @@ -19,6 +19,8 @@ #include +#include + #include "pbd/xml++.h" #include "pbd/convert.h" @@ -389,7 +391,7 @@ Bindings::save (const string& path) save (*root); if (!tree.write (path)) { - ::unlink (path.c_str()); + ::g_unlink (path.c_str()); return false; } diff --git a/libs/gtkmm2ext/motionfeedback.cc b/libs/gtkmm2ext/motionfeedback.cc index bd0fd1cd73..221a8b0bd6 100644 --- a/libs/gtkmm2ext/motionfeedback.cc +++ b/libs/gtkmm2ext/motionfeedback.cc @@ -25,6 +25,8 @@ #include #include /* for snprintf, grrr */ +#include + #include #include @@ -516,15 +518,15 @@ MotionFeedback::render_pixbuf (int size) pixbuf = Gdk::Pixbuf::create_from_file (path); } catch (const Gdk::PixbufError &e) { std::cerr << "Caught PixbufError: " << e.what() << std::endl; - unlink (path); + ::g_unlink (path); throw; } catch (...) { - unlink (path); + ::g_unlink (path); g_message("Caught ... "); throw; } - unlink (path); + ::g_unlink (path); g_free(path); diff --git a/libs/pbd/clear_dir.cc b/libs/pbd/clear_dir.cc index 29410d41e5..86f7067201 100644 --- a/libs/pbd/clear_dir.cc +++ b/libs/pbd/clear_dir.cc @@ -24,6 +24,7 @@ #include #include +#include #include #include "pbd/error.h" @@ -66,7 +67,7 @@ PBD::clear_directory (const string& dir, size_t* size, vector* paths) continue; } - if (::unlink (fullpath.c_str())) { + if (::g_unlink (fullpath.c_str())) { error << string_compose (_("cannot remove file %1 (%2)"), fullpath, strerror (errno)) << endmsg; ret = 1; diff --git a/libs/surfaces/frontier/kernel_drivers/tranzport.c b/libs/surfaces/frontier/kernel_drivers/tranzport.c index 6893f66921..b7b6709d56 100644 --- a/libs/surfaces/frontier/kernel_drivers/tranzport.c +++ b/libs/surfaces/frontier/kernel_drivers/tranzport.c @@ -445,7 +445,7 @@ static void usb_tranzport_interrupt_out_callback(struct urb *urb) { struct usb_tranzport *dev = urb->context; - /* sync/async unlink faults aren't errors */ + /* sync/async ::g_unlink faults aren't errors */ if (urb->status && !(urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 0c7c8455a4..8b57dc0c3e 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -181,7 +182,7 @@ OSC::start () int fd = mkstemp(tmpstr); if (fd >= 0 ) { - unlink (tmpstr); + ::g_unlink (tmpstr); close (fd); _osc_unix_server = lo_server_new (tmpstr, error_callback); @@ -284,11 +285,11 @@ OSC::stop () } if (!_osc_unix_socket_path.empty()) { - unlink (_osc_unix_socket_path.c_str()); + ::g_unlink (_osc_unix_socket_path.c_str()); } if (!_osc_url_file.empty() ) { - unlink (_osc_url_file.c_str() ); + ::g_unlink (_osc_url_file.c_str() ); } // Delete any active route observers