summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Emmas <johne53@tiscali.co.uk>2013-07-17 08:24:36 +0100
committerJohn Emmas <johne53@tiscali.co.uk>2013-07-17 08:24:36 +0100
commit57f9a4c344fc1142530d66283f07e9aa6524461c (patch)
tree400a30e66584302b8d3bc5af23d23c7bb21f1405
parent350ed31655b00f3043e5d723606cdd50099fa91b (diff)
parent15be15451592817731a271cd16d9b94c40c3023b (diff)
Merge branch 'windows' of git://git.ardour.org/ardour/ardour into windows
-rw-r--r--gtk2_ardour/ardour_ui.cc11
-rw-r--r--gtk2_ardour/ardour_ui.h14
-rw-r--r--gtk2_ardour/ardour_ui_dialogs.cc5
-rw-r--r--gtk2_ardour/audio_region_editor.cc30
-rw-r--r--gtk2_ardour/audio_region_editor.h10
-rw-r--r--gtk2_ardour/configinfo.cc10
-rw-r--r--gtk2_ardour/configinfo.h2
-rw-r--r--gtk2_ardour/editor_export_audio.cc6
-rw-r--r--gtk2_ardour/editor_videotimeline.cc4
-rw-r--r--gtk2_ardour/export_video_dialog.cc16
-rw-r--r--gtk2_ardour/gain_meter.cc2
-rw-r--r--gtk2_ardour/generic_pluginui.cc19
-rw-r--r--gtk2_ardour/lv2_plugin_ui.cc6
-rw-r--r--gtk2_ardour/meter_patterns.cc33
-rw-r--r--gtk2_ardour/meter_patterns.h2
-rw-r--r--gtk2_ardour/meter_strip.cc2
-rw-r--r--gtk2_ardour/meterbridge.cc3
-rw-r--r--gtk2_ardour/midi_tracer.cc3
-rw-r--r--gtk2_ardour/missing_file_dialog.cc17
-rw-r--r--gtk2_ardour/mixer_ui.cc2
-rw-r--r--gtk2_ardour/panner2d.cc12
-rw-r--r--gtk2_ardour/patch_change_dialog.cc2
-rw-r--r--gtk2_ardour/pingback.cc6
-rw-r--r--gtk2_ardour/sfdb_ui.cc8
-rw-r--r--gtk2_ardour/startup.cc2
-rw-r--r--gtk2_ardour/transcode_video_dialog.cc6
-rw-r--r--gtk2_ardour/utils.cc2
-rw-r--r--gtk2_ardour/wscript8
-rw-r--r--libs/ardour/ardour/audioengine.h3
-rw-r--r--libs/ardour/ardour/debug.h1
-rw-r--r--libs/ardour/ardour/directory_names.h1
-rw-r--r--libs/ardour/ardour/file_source.h2
-rw-r--r--libs/ardour/ardour/jack_utils.h261
-rw-r--r--libs/ardour/ardour/ladspa_search_path.h39
-rw-r--r--libs/ardour/ardour/plugin_manager.h3
-rw-r--r--libs/ardour/ardour/session.h2
-rw-r--r--libs/ardour/audio_unit.cc2
-rw-r--r--libs/ardour/audioengine.cc2
-rw-r--r--libs/ardour/audiofilesource.cc7
-rw-r--r--libs/ardour/audiosource.cc245
-rw-r--r--libs/ardour/debug.cc1
-rw-r--r--libs/ardour/directory_names.cc1
-rw-r--r--libs/ardour/export_handler.cc5
-rw-r--r--libs/ardour/file_source.cc34
-rw-r--r--libs/ardour/filesystem_paths.cc26
-rw-r--r--libs/ardour/import.cc3
-rw-r--r--libs/ardour/io.cc6
-rw-r--r--libs/ardour/jack_utils.cc947
-rw-r--r--libs/ardour/ladspa_search_path.cc61
-rw-r--r--libs/ardour/ltc_slave.cc4
-rw-r--r--libs/ardour/lv2_plugin.cc3
-rw-r--r--libs/ardour/midi_ui.cc2
-rw-r--r--libs/ardour/mtc_slave.cc7
-rw-r--r--libs/ardour/panner_manager.cc4
-rw-r--r--libs/ardour/plugin_manager.cc109
-rw-r--r--libs/ardour/port.cc2
-rw-r--r--libs/ardour/port_insert.cc2
-rw-r--r--libs/ardour/route.cc4
-rw-r--r--libs/ardour/session.cc69
-rw-r--r--libs/ardour/session_state.cc8
-rw-r--r--libs/ardour/smf_source.cc3
-rw-r--r--libs/ardour/test/jack_utils_test.cc315
-rw-r--r--libs/ardour/test/jack_utils_test.h33
-rw-r--r--libs/ardour/test/plugins_test.cc54
-rw-r--r--libs/ardour/test/plugins_test.h12
-rw-r--r--libs/ardour/wscript26
-rw-r--r--libs/audiographer/audiographer/sndfile/tmp_file.h5
-rw-r--r--libs/gtkmm2ext/barcontroller.cc6
-rw-r--r--libs/gtkmm2ext/bindings.cc4
-rw-r--r--libs/gtkmm2ext/fastmeter.cc17
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/dndvbox.h2
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/fastmeter.h1
-rw-r--r--libs/gtkmm2ext/motionfeedback.cc8
-rw-r--r--libs/gtkmm2ext/pixfader.cc16
-rw-r--r--libs/midi++2/jack_midi_port.cc6
-rw-r--r--libs/midi++2/midi++/jack_midi_port.h10
-rw-r--r--libs/midi++2/midi++/port.h2
-rw-r--r--libs/pbd/clear_dir.cc3
-rw-r--r--libs/pbd/debug.cc1
-rw-r--r--libs/pbd/file_manager.cc18
-rw-r--r--libs/pbd/file_utils.cc28
-rw-r--r--libs/pbd/pbd/abstract_ui.h14
-rw-r--r--libs/pbd/pbd/debug.h1
-rw-r--r--libs/pbd/pbd/floating.h2
-rw-r--r--libs/pbd/test/mutex_test.cc24
-rw-r--r--libs/pbd/test/mutex_test.h17
-rw-r--r--libs/pbd/test/testrunner.cc4
-rw-r--r--libs/pbd/wscript7
-rw-r--r--libs/surfaces/frontier/kernel_drivers/tranzport.c2
-rw-r--r--libs/surfaces/osc/osc.cc7
-rw-r--r--libs/surfaces/wscript2
-rw-r--r--libs/taglib/wscript1
-rw-r--r--tools/windows_packaging/mingw-env.sh4
-rw-r--r--tools/windows_packaging/package.sh4
-rw-r--r--tools/windows_packaging/pango.modules60
-rw-r--r--wscript51
96 files changed, 2416 insertions, 463 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 5bef863c95..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 */
@@ -903,8 +903,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;
@@ -1034,9 +1033,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;
@@ -4051,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<std::string> hits)
+ARDOUR_UI::ambiguous_file (std::string file, std::vector<std::string> hits)
{
AmbiguousFileDialog dialog (file, hits);
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index dd025b6f8b..7a8a0193f1 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<void,bool> Blink;
+
+ /** point_zero_one_seconds -- 10Hz ^= 100ms */
static sigc::signal<void> RapidScreenUpdate;
+
+ /** point_zero_something_seconds -- currently 25Hz ^= 40ms */
static sigc::signal<void> SuperRapidScreenUpdate;
+
/** Emitted frequently with the audible frame, false, and the edit point as
* parameters respectively.
+ *
+ * (either RapidScreenUpdate || SuperRapidScreenUpdate - user-config)
*/
static sigc::signal<void, framepos_t, bool, framepos_t> 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 ();
@@ -707,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<std::string> hits);
+ int ambiguous_file (std::string file, std::vector<std::string> hits);
bool click_button_clicked (GdkEventButton *);
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);
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<AudioRegion>
: 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<AudioRegion>
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
@@ -134,12 +136,32 @@ 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 <libgnomecanvas/libgnomecanvas.h>
#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<void, double> 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__ */
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 <gtkmm/textview.h>
+#include <gtkmm/scrolledwindow.h>
#include "ardour_dialog.h"
@@ -28,4 +29,5 @@ class ConfigInfoDialog : public ArdourDialog
private:
Gtk::TextView text;
+ Gtk::ScrolledWindow scroller;
};
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 <gtkmm/messagedialog.h>
+#include <glib/gstdio.h>
+
#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 <jack/types.h>
+#include <glib/gstdio.h>
+
#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 <sigc++/bind.h>
#include <libgen.h>
+#include <glib/gstdio.h>
+
#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/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/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc
index c66a1fec38..6cea8f3c0b 100644
--- a/gtk2_ardour/generic_pluginui.cc
+++ b/gtk2_ardour/generic_pluginui.cc
@@ -659,7 +659,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
control_ui->display_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 ();
@@ -669,7 +669,17 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
MeterInfo * info = new MeterInfo(port_index);
control_ui->meterinfo = 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;
@@ -680,6 +690,9 @@ GenericPluginUI::build_control_ui (guint32 port_index, boost::shared_ptr<Automat
control_ui->vbox = 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);
@@ -834,7 +847,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 {
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<ARDOUR::DataType> 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<ARDOUR::DataT
gint meter_expose_ticks (GdkEventExpose *ev, std::vector<ARDOUR::DataType> types, Gtk::DrawingArea *mta);
gint meter_expose_metrics (GdkEventExpose *ev, std::vector<ARDOUR::DataType> 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 74c13f45eb..24b21656d1 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()));
@@ -325,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;
diff --git a/gtk2_ardour/midi_tracer.cc b/gtk2_ardour/midi_tracer.cc
index 70d7c24da6..e447c59f3b 100644
--- a/gtk2_ardour/midi_tracer.cc
+++ b/gtk2_ardour/midi_tracer.cc
@@ -23,6 +23,9 @@
#include <sys/time.h>
#include <time.h>
+#include "pbd/localtime_r.h"
+#include "pbd/timersub.h"
+
#include "midi++/parser.h"
#include "midi++/manager.h"
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<string> source_dirs = s->source_search_path (type);
+ vector<string>::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<i>%3</i>\n\nin any of these folders:\n\n\
-<tt>%4</tt>\n\n"), PROGRAM_NAME, typestr, Glib::Markup::escape_text(path), Glib::Markup::escape_text (dirstr)));
+<tt>%4</tt>\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/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()));
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 */
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);
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 <fstream>
#include <cstring>
+#ifndef WIN32
#include <sys/utsname.h>
+#endif
+
#include <curl/curl.h>
#include <glibmm/miscutils.h>
@@ -70,6 +73,7 @@ struct ping_call {
static void*
_pingback (void *arg)
{
+#ifndef WIN32
ping_call* cm = static_cast<ping_call*> (arg);
CURL* c;
struct utsname utb;
@@ -158,6 +162,8 @@ _pingback (void *arg)
curl_easy_cleanup (c);
delete cm;
+#endif /* WIN32 */
+
return 0;
}
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index e8db9d4939..f116041d03 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -31,6 +31,8 @@
#include <gtkmm/box.h>
#include <gtkmm/stock.h>
+
+#include <glib/gstdio.h>
#include <glibmm/fileutils.h>
#include "pbd/convert.h"
@@ -1463,6 +1465,9 @@ SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool&
bool
SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
{
+#ifdef WIN32
+ return false;
+#else
std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
bool ret = false;
@@ -1484,7 +1489,7 @@ SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths
goto out;
}
- unlink (tmpc);
+ ::g_unlink (tmpc);
}
ret = true;
@@ -1492,6 +1497,7 @@ SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths
out:
rmdir (tmpdir.c_str());
return ret;
+#endif
}
SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
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
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 <sigc++/bind.h>
#include <libgen.h>
+#include <glib/gstdio.h>
+
#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/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 */
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/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 <jack/weakjack.h>
+#endif
+
#include <jack/jack.h>
#include <jack/transport.h>
#include <jack/thread.h>
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/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/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<int,std::string,std::string,std::vector<std::string> > AmbiguousFileName;
+ static PBD::Signal2<int,std::string,std::vector<std::string> > AmbiguousFileName;
protected:
FileSource (Session& session, DataType type,
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 <stdint.h>
+
+#include <vector>
+#include <map>
+#include <string>
+
+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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string, std::string> 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<std::string> 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<std::string>& 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<std::string>&);
+
+ /**
+ * 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<std::string>& 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<std::string>& server_dir_paths,
+ const std::vector<std::string>& server_names,
+ std::vector<std::string>& server_paths);
+
+
+ bool get_jack_server_paths (std::vector<std::string>& 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/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/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<uint32_t, std::string> 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/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<std::string> source_search_path(DataType) const;
void ensure_search_path_includes (const std::string& path, DataType type);
std::list<std::string> unknown_processors () const;
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/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 <jack/weakjack.h>
-
#include "midi++/port.h"
#include "midi++/jack_midi_port.h"
#include "midi++/mmc.h"
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 <sndfile.h>
+#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include <glibmm/fileutils.h>
#include <glibmm/threads.h>
@@ -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 da9be81007..e224186bd2 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -30,6 +30,12 @@
#include <algorithm>
#include <vector>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <boost/scoped_array.hpp>
+#include <boost/scoped_ptr.hpp>
+
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
@@ -41,6 +47,8 @@
#include "i18n.h"
+#include "ardour/debug.h"
+
using namespace std;
using namespace ARDOUR;
using namespace PBD;
@@ -174,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;
}
@@ -183,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
@@ -194,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;
}
@@ -212,13 +220,15 @@ 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)) {
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 */
@@ -226,7 +236,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 +245,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 +257,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;
@@ -315,28 +326,15 @@ 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;
- PeakData* staging = 0;
- Sample* raw_staging = 0;
- FdFileDescriptor* peakfile_descriptor = new FdFileDescriptor (peakpath, false, 0664);
+ boost::scoped_ptr<FdFileDescriptor> peakfile_descriptor(new FdFileDescriptor (peakpath, false, 0664));
int peakfile_fd = -1;
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
- <<endl;
-
-#endif
+ DEBUG_TRACE (DEBUG::Peaks, string_compose (" ======>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,16 +350,15 @@ 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.
*/
- Sample* raw_staging = new Sample[cnt];
+ boost::scoped_array<Sample> 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;
}
@@ -371,45 +368,35 @@ 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;
}
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) {
error << string_compose(_("AudioSource: cannot open peakpath (a) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
- delete peakfile_descriptor;
return -1;
}
-#ifdef DEBUG_READ_PEAKS
- cerr << "DIRECT PEAKS\n";
-#endif
-
-#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;
- delete peakfile_descriptor;
+ DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n");
+
+ offset = lseek (peakfile_fd, first_peak_byte, SEEK_SET);
+
+ 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;
}
@@ -417,7 +404,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;
}
@@ -426,9 +412,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,
@@ -441,7 +426,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<PeakData> staging(new PeakData[chunksize]);
/* compute the rounded up frame position */
@@ -462,8 +447,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;
}
@@ -474,34 +457,27 @@ 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;
-#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"
+ , bytes_to_read, start_byte));
-#ifndef WIN32
- if ((nread = ::pread (peakfile_fd, staging, 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);
- 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;
- goto out;
+ 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));
+ return -1;
}
-#endif
i = 0;
stored_peaks_read = nread / sizeof(PeakData);
}
@@ -532,13 +508,10 @@ AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t
memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
}
- ret = 0;
-
} else {
-#ifdef DEBUG_READ_PEAKS
- cerr << "UPSAMPLE\n";
-#endif
+ DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n");
+
/* the caller wants
- less frames-per-peak (more resolution)
@@ -553,7 +526,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<Sample> raw_staging(new Sample[chunksize]);
framepos_t frame_pos = start;
double pixel_pos = floor (frame_pos / samples_per_visual_peak);
@@ -578,18 +551,18 @@ 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;
- goto out;
+ return -1;
}
}
@@ -617,32 +590,19 @@ 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:
- delete peakfile_descriptor;
-
- delete [] staging;
- delete [] raw_staging;
-
-#ifdef DEBUG_READ_PEAKS
- cerr << "RP DONE\n";
-#endif
-
- return ret;
+ DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n");
+ return 0;
}
-#undef DEBUG_PEAK_BUILD
-
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");
+
int ret = -1;
{
@@ -658,20 +618,20 @@ AudioSource::build_peaks_from_scratch ()
framecnt_t cnt = _length;
_peaks_built = false;
- buf = new Sample[bufsize];
+ boost::scoped_array<Sample> 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;
}
@@ -692,11 +652,10 @@ AudioSource::build_peaks_from_scratch ()
out:
if (ret) {
- unlink (peakpath.c_str());
+ DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", peakpath));
+ ::g_unlink (peakpath.c_str());
}
- delete [] buf;
-
return ret;
}
@@ -740,15 +699,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<Sample> buf2;
if (_peakfile_descriptor == 0) {
prepare_for_peakfile_writes ();
@@ -771,12 +728,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;
- goto out;
+ return -1;
}
-#endif
+
_peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
{
@@ -800,19 +763,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 */
@@ -822,7 +785,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<PeakData> peakbuf(new PeakData[(to_do/fpp)+1]);
peaks_computed = 0;
current_frame = first_frame;
frames_done = 0;
@@ -879,20 +842,31 @@ 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 */
}
}
}
-#ifndef WIN32
- if (::pwrite (_peakfile_fd, peakbuf, 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;
- goto out;
+ 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);
@@ -902,13 +876,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
@@ -925,6 +893,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");
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 */
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 <glib/gstdio.h>
#include <glibmm.h>
#include <glibmm/convert.h>
@@ -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/file_source.cc b/libs/ardour/file_source.cc
index 0921498186..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<int,std::string,std::string,std::vector<std::string> > FileSource::AmbiguousFileName;
+PBD::Signal2<int,std::string,std::vector<std::string> > 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<string> dirs;
vector<string> hits;
string fullpath;
+ std::vector<std::string> 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<string>::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<string> dirs;
+ vector<string> 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<string>::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;
@@ -496,13 +487,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;
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;
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 <sndfile.h>
#include <samplerate.h>
+#include <glib/gstdio.h>
#include <glibmm.h>
#include <boost/scoped_array.hpp>
@@ -464,7 +465,7 @@ remove_file_source (boost::shared_ptr<Source> source)
boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
if (fs) {
- ::unlink (fs->path().c_str());
+ ::g_unlink (fs->path().c_str());
}
}
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> 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/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 <alsa/asoundlib.h>
+#endif
+
+#ifdef __APPLE__
+#include <CoreAudio/CoreAudio.h>
+#include <CoreFoundation/CFString.h>
+#include <sys/param.h>
+#include <mach-o/dyld.h>
+#endif
+
+#ifdef HAVE_PORTAUDIO
+#include <portaudio.h>
+#endif
+
+#include <jack/jack.h>
+
+#include <fstream>
+
+#include <boost/scoped_ptr.hpp>
+
+#include <glibmm/miscutils.h>
+
+#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 <CFBundle.h>
+#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<string>& 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<string> drivers;
+ get_jack_audio_driver_names (drivers);
+ audio_driver_name = drivers.front ();
+}
+
+void
+ARDOUR::get_jack_midi_system_names (const string& driver, vector<string>& 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<string> drivers;
+ get_jack_midi_system_names (driver, drivers);
+ midi_system_name = drivers.front ();
+}
+
+void
+ARDOUR::get_jack_sample_rate_strings (vector<string>& 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<std::string>& 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<string>& 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<EnvironmentalProtectionAgency> 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<std::string>
+ARDOUR::get_jack_device_names_for_audio_driver (const string& driver_name)
+{
+ std::vector<std::string> 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& server_dir_paths,
+ const vector<string>& server_names,
+ vector<std::string>& server_paths)
+{
+ for (vector<string>::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<std::string>& server_paths)
+{
+ vector<std::string> server_dirs;
+
+ if (!get_jack_server_dir_paths (server_dirs)) {
+ return false;
+ }
+
+ vector<string> 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<std::string> 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<string> 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<string>::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/ladspa_search_path.cc b/libs/ardour/ladspa_search_path.cc
new file mode 100644
index 0000000000..6ecc1557a3
--- /dev/null
+++ b/libs/ardour/ladspa_search_path.cc
@@ -0,0 +1,61 @@
+/*
+ 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 <glibmm/miscutils.h>
+
+#include "pbd/pathexpand.h"
+
+#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");
+#endif
+
+#ifdef __APPLE__
+ spath.push_back (expand_path ("~/Library/Audio/Plug-Ins/LADSPA"));
+ spath.push_back ("/Library/Audio/Plug-Ins/LADSPA");
+#endif
+
+ return spath_env + spath;
+}
+
+} // namespace ARDOUR
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 <iostream>
#include <errno.h>
-#include <poll.h>
#include <sys/types.h>
#include <unistd.h>
#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;
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 <cstdlib>
#include <cstring>
+#include <glib/gstdio.h>
#include <giomm/file.h>
#include <glib/gprintf.h>
#include <glibmm.h>
@@ -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/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/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 <unistd.h>
#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++;
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<std::string>::iterator i = panner_modules.begin(); i != panner_modules.end(); ++i) {
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 <glibmm/miscutils.h>
+#include <glibmm/pattern.h>
#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<string> 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 += ":";
-
- ladspa_path += standard_paths[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));
-}
+ DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
-int
-PluginManager::ladspa_discover_from_path (string /*path*/)
-{
- PathScanner scanner;
- vector<string *> *plugin_objects;
- vector<string *>::iterator x;
- int ret = 0;
+ Glib::PatternSpec so_extension_pattern("*.so");
+ Glib::PatternSpec dylib_extension_pattern("*.dylib");
+ Glib::PatternSpec dll_extension_pattern("*.dll");
- plugin_objects = scanner (ladspa_path, ladspa_filter, 0, false, true);
+ find_matching_files_in_search_path (ladspa_search_path (),
+ so_extension_pattern, ladspa_modules);
- if (plugin_objects) {
- for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
- ladspa_discover (**x);
- }
+ 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);
- vector_delete (plugin_objects);
+ for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
+ ladspa_discover (*i);
}
-
- 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
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 <jack/weakjack.h> // so that we can test for new functions at runtime
+#endif
#include "pbd/compose.h"
#include "pbd/error.h"
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;
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<std::string>
Session::source_search_path (DataType type) const
{
- vector<string> 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<string> 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<string>::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<string>::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<string> 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<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
+ for (vector<std::string>::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;
}
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 7ccaca1a27..62edaa3911 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;
@@ -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 <glib/gstdio.h>
#include <glibmm/miscutils.h>
#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/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 <stdexcept>
+
+#ifdef WIN32
+#include <windows.h> // only for Sleep
+#endif
+
+#include <glibmm/miscutils.h>
+
+#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<string> 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<string>::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<string>::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<string>& devices)
+{
+ std::string str;
+ for (vector<string>::const_iterator i = devices.begin(); i != devices.end();) {
+ str += *i;
+ if (++i != devices.end()) str += ", ";
+ }
+ return str;
+}
+
+void
+JackUtilsTest::test_device_names ()
+{
+ vector<string> driver_names;
+
+ get_jack_audio_driver_names (driver_names);
+
+ CPPUNIT_ASSERT(!driver_names.empty());
+
+ cout << endl;
+
+ for (vector<string>::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<string> samplerates;
+
+ get_jack_sample_rate_strings (samplerates);
+ cout << endl;
+ cout << "Number of possible Samplerates supported by JACK: " << samplerates.size () << endl;
+
+ for (vector<string>::const_iterator i = samplerates.begin(); i != samplerates.end(); ++i) {
+ cout << "Samplerate: " << *i << endl;
+ }
+}
+
+void
+JackUtilsTest::test_period_sizes ()
+{
+ vector<string> 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<string>::const_iterator i = period_sizes.begin(); i != period_sizes.end(); ++i) {
+ cout << "Period size: " << *i << endl;
+ }
+}
+
+void
+JackUtilsTest::test_dither_modes ()
+{
+ vector<string> driver_names;
+
+ get_jack_audio_driver_names (driver_names);
+
+ CPPUNIT_ASSERT(!driver_names.empty());
+
+ cout << endl;
+
+ for (vector<string>::const_iterator i = driver_names.begin(); i != driver_names.end(); ++i) {
+ vector<string> 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<string>::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<string> 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<std::string> 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<std::string>::const_iterator i = server_dirs.begin(); i != server_dirs.end(); ++i) {
+ cout << "JACK server directory path: " << *i << endl;
+ }
+
+ vector<string> 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<string>::const_iterator i = server_names.begin(); i != server_names.end(); ++i) {
+ cout << "JACK server name: " << *i << endl;
+ }
+
+ vector<std::string> 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<std::string>::const_iterator i = server_paths.begin(); i != server_paths.end(); ++i) {
+ cout << "JACK server path: " << *i << endl;
+ }
+
+ vector<std::string> 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<string> 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<string> 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 <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+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/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 <iostream>
+
+#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<std::string>::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 <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+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 4e7e23aa1a..5e8b27d4ea 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,8 +100,10 @@ libardour_sources = [
'io.cc',
'io_processor.cc',
'jack_slave.cc',
+ 'jack_utils.cc',
'kmeterdsp.cc',
'ladspa_plugin.cc',
+ 'ladspa_search_path.cc',
'location.cc',
'location_importer.cc',
'ltc_slave.cc',
@@ -235,13 +238,20 @@ 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':
+ 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')
+ 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',
@@ -378,8 +388,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']
@@ -478,8 +488,10 @@ 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'])
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'])
@@ -495,8 +507,10 @@ 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
test/region_naming_test.cc
test/control_surfaces_test.cc
test/mtdm_test.cc
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 <cstdio>
#include <string>
+#include <glib.h>
+#include <glib/gstdio.h>
+
#include "sndfile_writer.h"
#include "sndfile_reader.h"
@@ -18,7 +21,7 @@ class TmpFile : public SndfileWriter<T>, public SndfileReader<T>
/// \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)
{}
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/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 <iostream>
+#include <glib/gstdio.h>
+
#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/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<Gdk::Window> 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/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);
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*);
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 <unistd.h>
#include <stdio.h> /* for snprintf, grrr */
+#include <glib/gstdio.h>
+
#include <gdk/gdkkeysyms.h>
#include <gtkmm.h>
@@ -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/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;
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<double> > output_fifo;
Evoral::EventRingBuffer<timestamp_t> 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 <pthread.h>
#include "pbd/xml++.h"
+#ifndef WIN32
#include "pbd/crossthread.h"
+#endif
#include "pbd/signals.h"
#include "pbd/ringbuffer.h"
diff --git a/libs/pbd/clear_dir.cc b/libs/pbd/clear_dir.cc
index 2ad3b73bb3..2f9c7b772d 100644
--- a/libs/pbd/clear_dir.cc
+++ b/libs/pbd/clear_dir.cc
@@ -32,6 +32,7 @@ using PBD::closedir;
#include <errno.h>
#include <string.h>
+#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include "pbd/error.h"
@@ -74,7 +75,7 @@ PBD::clear_directory (const string& dir, size_t* size, vector<string>* 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/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_manager.cc b/libs/pbd/file_manager.cc
index e02bcc2b0d..2cfa63ae39 100644
--- a/libs/pbd/file_manager.cc
+++ b/libs/pbd/file_manager.cc
@@ -24,6 +24,9 @@
#include <cassert>
#include <cstdio>
+#include <glib.h>
+#include <glib/gstdio.h>
+
#ifdef __APPLE__
#include <mach/mach_time.h>
#endif
@@ -225,8 +228,19 @@ bool
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);
+
+ /* 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);
}
diff --git a/libs/pbd/file_utils.cc b/libs/pbd/file_utils.cc
index 03c3ea853c..50287149e1 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/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<pthread_t,RequestBuffer*, pthread_cmp>::iterator RequestBufferMapIterator;
+ typedef std::map<pthread_t,RequestBuffer*, pthread_cmp> RequestBufferMap;
+#else
typedef typename std::map<pthread_t,RequestBuffer*>::iterator RequestBufferMapIterator;
typedef std::map<pthread_t,RequestBuffer*> RequestBufferMap;
+#endif
RequestBufferMap request_buffers;
static Glib::Threads::Private<RequestBuffer> per_thread_request_buffer;
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;
}
}
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 <stdint.h>
+
#include <cmath>
namespace PBD {
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 <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#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;
+};
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 <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <cppunit/BriefTestProgressListener.h>
+#include <glibmm/thread.h>
#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..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'
@@ -144,6 +146,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
@@ -155,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/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 <unistd.h>
#include <fcntl.h>
+#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include <pbd/pthread_utils.h>
@@ -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
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/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/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
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:*
diff --git a/wscript b/wscript
index a6106c0aef..148b843a61 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)')
@@ -591,13 +590,6 @@ def configure(conf):
autowaf.check_header(conf, 'cxx', 'jack/session.h', define="JACK_SESSION", mandatory = False)
- conf.check_cxx(fragment = "#include <boost/version.hpp>\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')
@@ -606,7 +598,28 @@ 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')
+
+ conf.check_cxx(fragment = "#include <boost/version.hpp>\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
@@ -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)