# /libs/pbd/
/libs/pbd/version.cc
/libs/pbd/pbd/version.h
+
+/libs/taglib/taglib/flacproperties.h
+/libs/taglib/taglib/apefooter.h
+/libs/taglib/taglib/apeitem.h
+/libs/taglib/taglib/apetag.h
+/libs/taglib/taglib/attachedpictureframe.h
+/libs/taglib/taglib/commentsframe.h
+/libs/taglib/taglib/flacfile.h
+/libs/taglib/taglib/id3v2tag.h
+/libs/taglib/taglib/generalencapsulatedobjectframe.h
+/libs/taglib/taglib/id3v1genres.h
+/libs/taglib/taglib/id3v1tag.h
+/libs/taglib/taglib/id3v2extendedheader.h
+/libs/taglib/taglib/id3v2footer.h
+/libs/taglib/taglib/id3v2frame.h
+/libs/taglib/taglib/id3v2framefactory.h
+/libs/taglib/taglib/id3v2header.h
+/libs/taglib/taglib/id3v2synchdata.h
+/libs/taglib/taglib/oggpageheader.h
+/libs/taglib/taglib/mpcfile.h
+/libs/taglib/taglib/mpcproperties.h
+/libs/taglib/taglib/mpegfile.h
+/libs/taglib/taglib/mpegheader.h
+/libs/taglib/taglib/mpegproperties.h
+/libs/taglib/taglib/oggfile.h
+/libs/taglib/taglib/oggflacfile.h
+/libs/taglib/taglib/oggpage.h
+/libs/taglib/taglib/textidentificationframe.h
+/libs/taglib/taglib/relativevolumeframe.h
+/libs/taglib/taglib/speexfile.h
+/libs/taglib/taglib/speexproperties.h
+/libs/taglib/taglib/taglib.h
+/libs/taglib/taglib/tbytevector.h
+/libs/taglib/taglib/tbytevectorlist.h
+/libs/taglib/taglib/tdebug.h
+/libs/taglib/taglib/tlist.h
+/libs/taglib/taglib/tmap.h
+/libs/taglib/taglib/trueaudiofile.h
+/libs/taglib/taglib/trueaudioproperties.h
+/libs/taglib/taglib/tstring.h
+/libs/taglib/taglib/tstringlist.h
+/libs/taglib/taglib/tfile.h
+/libs/taglib/taglib/urllinkframe.h
+/libs/taglib/taglib/unicode.h
+/libs/taglib/taglib/uniquefileidentifierframe.h
+/libs/taglib/taglib/unknownframe.h
+/libs/taglib/taglib/unsynchronizedlyricsframe.h
+/libs/taglib/taglib/xiphcomment.h
+/libs/taglib/taglib/vorbisfile.h
+/libs/taglib/taglib/vorbisproperties.h
+/libs/taglib/taglib/wavpackfile.h
+/libs/taglib/taglib/wavpackproperties.h
+/libs/taglib/taglib/xingheader.h
+/libs/taglib/taglib/tlist.tcc
+/libs/taglib/taglib/tmap.tcc
\ No newline at end of file
#include <algorithm>
#include <unistd.h>
#include <sys/types.h>
-#include <sys/wait.h>
#include <cstdio>
#include <ctime>
#include <cstdlib>
std::string splash_file;
- SearchPath spath(ardour_data_search_path());
+ Searchpath spath(ardour_data_search_path());
if (find_file_in_search_path (spath, "splash.png", splash_file)) {
set_logo (Gdk::Pixbuf::create_from_file (splash_file));
#include <cerrno>
#include <fstream>
+#ifndef WIN32
+#include <sys/resource.h>
+#endif
+
#include <stdint.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <sys/sysctl.h>
+#include <glib.h>
+#include <glib/gstdio.h>
#include <gtkmm/messagedialog.h>
#include <gtkmm/accelmap.h>
#include "pbd/memento_command.h"
#include "pbd/openuri.h"
#include "pbd/file_utils.h"
+#include "pbd/localtime_r.h"
#include "gtkmm2ext/application.h"
#include "gtkmm2ext/bindings.h"
/* 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 */
void
ARDOUR_UI::check_memory_locking ()
{
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(WIN32)
/* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
return;
#else // !__APPLE__
if (icsd_docroot.empty()) {icsd_docroot = X_("/");}
struct stat sb;
- if (!lstat (icsd_docroot.c_str(), &sb) == 0 || !S_ISDIR(sb.st_mode)) {
+ if (!g_lstat (icsd_docroot.c_str(), &sb) == 0 || !S_ISDIR(sb.st_mode)) {
warning << _("Specified docroot is not an existing directory.") << endmsg;
continue;
}
- if ( (!lstat (icsd_exec.c_str(), &sb) == 0)
+#ifndef WIN32
+ if ( (!g_lstat (icsd_exec.c_str(), &sb) == 0)
|| (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0 ) {
warning << _("Given Video Server is not an executable file.") << endmsg;
continue;
}
+#else
+ if ( (!g_lstat (icsd_exec.c_str(), &sb) == 0)
+ || (sb.st_mode & (S_IXUSR)) == 0 ) {
+ warning << _("Given Video Server is not an executable file.") << endmsg;
+ continue;
+ }
+#endif
char **argp;
argp=(char**) calloc(9,sizeof(char*));
}
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);
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 *);
#include "ardour/audioengine.h"
#include "ardour/automation_watch.h"
+#ifdef interface
+#undef interface
+#endif
+
#include "actions.h"
#include "add_route_dialog.h"
#include "add_video_dialog.h"
: 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);
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 ()
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
}
}
+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 */
#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"
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__ */
#ifndef __gtk_ardour_audio_region_view_h__
#define __gtk_ardour_audio_region_view_h__
+#ifdef interface
+#undef interface
+#endif
+
#include <vector>
#include <libgnomecanvasmm.h>
MenuList& automation_items = automation_action_menu->items ();
automation_items.push_back (CheckMenuElem (_("Fader"), sigc::mem_fun (*this, &AudioTimeAxisView::update_gain_track_visibility)));
- gain_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ());
+ gain_automation_item = dynamic_cast<Gtk::CheckMenuItem*> (&automation_items.back ());
gain_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) &&
(gain_track && string_is_affirmative (gain_track->gui_property ("visible"))));
_main_automation_menu_map[Evoral::Parameter(GainAutomation)] = gain_automation_item;
automation_items.push_back (CheckMenuElem (_("Pan"), sigc::mem_fun (*this, &AudioTimeAxisView::update_pan_track_visibility)));
- pan_automation_item = dynamic_cast<CheckMenuItem*> (&automation_items.back ());
+ pan_automation_item = dynamic_cast<Gtk::CheckMenuItem*> (&automation_items.back ());
pan_automation_item->set_active ((!for_selection || _editor.get_selection().tracks.size() == 1) &&
(!pan_tracks.empty() && string_is_affirmative (pan_tracks.front()->gui_property ("visible"))));
as_items.push_back (CheckMenuElem (S_("Automation|Manual"), sigc::bind (
sigc::mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
(AutoState) ARDOUR::Off)));
- auto_off_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
+ auto_off_item = dynamic_cast<Gtk::CheckMenuItem*>(&as_items.back());
as_items.push_back (CheckMenuElem (_("Play"), sigc::bind (
sigc::mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
(AutoState) Play)));
- auto_play_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
+ auto_play_item = dynamic_cast<Gtk::CheckMenuItem*>(&as_items.back());
as_items.push_back (CheckMenuElem (_("Write"), sigc::bind (
sigc::mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
(AutoState) Write)));
- auto_write_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
+ auto_write_item = dynamic_cast<Gtk::CheckMenuItem*>(&as_items.back());
as_items.push_back (CheckMenuElem (_("Touch"), sigc::bind (
sigc::mem_fun(*this, &AutomationTimeAxisView::set_automation_state),
(AutoState) Touch)));
- auto_touch_item = dynamic_cast<CheckMenuItem*>(&as_items.back());
+ auto_touch_item = dynamic_cast<Gtk::CheckMenuItem*>(&as_items.back());
items.push_back (MenuElem (_("State"), *auto_state_menu));
am_items.push_back (RadioMenuElem (group, _("Discrete"), sigc::bind (
sigc::mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
AutomationList::Discrete)));
- mode_discrete_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
+ mode_discrete_item = dynamic_cast<Gtk::CheckMenuItem*>(&am_items.back());
mode_discrete_item->set_active (s == AutomationList::Discrete);
am_items.push_back (RadioMenuElem (group, _("Linear"), sigc::bind (
sigc::mem_fun(*this, &AutomationTimeAxisView::set_interpolation),
AutomationList::Linear)));
- mode_line_item = dynamic_cast<CheckMenuItem*>(&am_items.back());
+ mode_line_item = dynamic_cast<Gtk::CheckMenuItem*>(&am_items.back());
mode_line_item->set_active (s == AutomationList::Linear);
items.push_back (MenuElem (_("Mode"), *auto_mode_menu));
edit_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::EDIT, Gtk::ICON_SIZE_BUTTON)));
edit_button.signal_clicked().connect (sigc::mem_fun (*this, &BundleManager::edit_clicked));
buttons->pack_start (edit_button, false, false);
- delete_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::DELETE, Gtk::ICON_SIZE_BUTTON)));
+ delete_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID(GTK_STOCK_DELETE), Gtk::ICON_SIZE_BUTTON)));
delete_button.signal_clicked().connect (sigc::mem_fun (*this, &BundleManager::delete_clicked));
buttons->pack_start (delete_button, false, false);
/* POSIX guarantees casting between void* and function pointers, ISO C doesn't
* We can work around warnings by going one step deeper in our casts
*/
-#ifdef _POSIX_VERSION
+#if defined(_POSIX_VERSION) || defined(__MINGW32__)
#define POSIX_FUNC_PTR_CAST(type, object) *((type*) &(object))
#endif // _POSIX_VERSION
#include <gtkmm/messagedialog.h>
+#include <glib/gstdio.h>
+
#include "gtkmm2ext/choice.h"
#include "pbd/pthread_utils.h"
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;
items.push_back (MenuElem (_("Rename..."), sigc::mem_fun(*this, &Editor::marker_menu_rename)));
items.push_back (CheckMenuElem (_("Lock")));
- CheckMenuItem* lock_item = static_cast<CheckMenuItem*> (&items.back());
+ Gtk::CheckMenuItem* lock_item = static_cast<Gtk::CheckMenuItem*> (&items.back());
if (loc->locked ()) {
lock_item->set_active ();
}
lock_item->signal_activate().connect (sigc::mem_fun (*this, &Editor::toggle_marker_menu_lock));
items.push_back (CheckMenuElem (_("Glue to Bars and Beats")));
- CheckMenuItem* glue_item = static_cast<CheckMenuItem*> (&items.back());
+ Gtk::CheckMenuItem* glue_item = static_cast<Gtk::CheckMenuItem*> (&items.back());
if (loc->position_lock_style() == MusicTime) {
glue_item->set_active ();
}
ruler_items.push_back (MenuElem (_("Timeline height")));
static_cast<MenuItem*>(&ruler_items.back())->set_sensitive(false);
ruler_items.push_back (CheckMenuElem (_("Large"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 6)));
- if (videotl_bar_height == 6) { static_cast<CheckMenuItem*>(&ruler_items.back())->set_active(true);}
+ if (videotl_bar_height == 6) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
ruler_items.push_back (CheckMenuElem (_("Normal"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 4)));
- if (videotl_bar_height == 4) { static_cast<CheckMenuItem*>(&ruler_items.back())->set_active(true);}
+ if (videotl_bar_height == 4) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
ruler_items.push_back (CheckMenuElem (_("Small"), sigc::bind ( sigc::mem_fun(*this, &Editor::set_video_timeline_height), 3)));
- if (videotl_bar_height == 3) { static_cast<CheckMenuItem*>(&ruler_items.back())->set_active(true);}
+ if (videotl_bar_height == 3) { static_cast<Gtk::CheckMenuItem*>(&ruler_items.back())->set_active(true);}
ruler_items.push_back (SeparatorElem ());
ruler_items.push_back (MenuElem (_("Align Video Track")));
ruler_items.push_back (CheckMenuElem (_("Lock")));
{
- CheckMenuItem* vtl_lock = static_cast<CheckMenuItem*>(&ruler_items.back());
+ Gtk::CheckMenuItem* vtl_lock = static_cast<Gtk::CheckMenuItem*>(&ruler_items.back());
vtl_lock->set_active(is_video_timeline_locked());
vtl_lock->signal_activate().connect (sigc::mem_fun(*this, &Editor::toggle_video_timeline_locked));
}
by the GUI ...
*/
+#ifdef WIN32
+ Sleep(2000);
+#else
struct timespec t = { 2, 0 };
nanosleep (&t, 0);
-
+#endif
return 0;
}
#include <jack/types.h>
+#include <glib/gstdio.h>
+
#include "ardour/profile.h"
#include "ardour/rc_configuration.h"
#include "ardour/audio_track.h"
import_status.all_done = true;
#endif
- unlink(path.c_str());
+ ::g_unlink(path.c_str());
}
void
#include "ardour/export_profile_manager.h"
+#ifdef interface
+#undef interface
+#endif
+
#include <gtkmm.h>
#include <sigc++/signal.h>
#include <boost/shared_ptr.hpp>
if (gtk_events_pending()) {
gtk_main_iteration ();
} else {
- usleep (10000);
+ Glib::usleep (10000);
}
}
#include "ardour_dialog.h"
#include "audio_clock.h"
+#ifdef interface
+#undef interface
+#endif
+
#include <gtkmm.h>
class ExportFormatDialog : public ArdourDialog, public PBD::ScopedConnectionList {
#include <list>
+#ifdef interface
+#undef interface
+#endif
+
#include <gtkmm.h>
#include <boost/shared_ptr.hpp>
+
#include "ardour/types.h"
#include "ardour/session_handle.h"
#include "ardour/export_profile_manager.h"
#include <sigc++/bind.h>
+#include <glib/gstdio.h>
+
#include "pbd/error.h"
#include "pbd/convert.h"
#include "gtkmm2ext/utils.h"
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;
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);
}
}
audio_progress_connection.disconnect();
status->finish ();
if (status->aborted()) {
- unlink (insnd.c_str());
+ ::g_unlink (insnd.c_str());
Gtk::Dialog::response(RESPONSE_CANCEL);
return;
}
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;
}
*/
#include "ardour/session.h"
+#ifdef interface
+#undef interface
+#endif
#include "export_video_infobox.h"
#include "i18n.h"
#include "ardour/plugin_insert.h"
#include "ardour/session.h"
-#include <lrdf.h>
-
#include "ardour_ui.h"
#include "prompter.h"
#include "plugin_ui.h"
}
_ports[dim].suspend_signals ();
- _ports[dim].gather (_session, type(), dim == IN, false, show_only_bundles ());
+ _ports[dim].gather (_session, type(), dim == FLOW_IN, false, show_only_bundles ());
_ports[dim].resume_signals ();
}
return;
}
- Bundle::PortList const & in_ports = c[IN].bundle->channel_ports (c[IN].channel);
- Bundle::PortList const & out_ports = c[OUT].bundle->channel_ports (c[OUT].channel);
+ Bundle::PortList const & in_ports = c[FLOW_IN].bundle->channel_ports (c[FLOW_IN].channel);
+ Bundle::PortList const & out_ports = c[FLOW_OUT].bundle->channel_ports (c[FLOW_OUT].channel);
for (Bundle::PortList::const_iterator i = in_ports.begin(); i != in_ports.end(); ++i) {
for (Bundle::PortList::const_iterator j = out_ports.begin(); j != out_ports.end(); ++j) {
return PortMatrixNode::NOT_ASSOCIATED;
}
- Bundle::PortList const & in_ports = c[IN].bundle->channel_ports (c[IN].channel);
- Bundle::PortList const & out_ports = c[OUT].bundle->channel_ports (c[OUT].channel);
+ Bundle::PortList const & in_ports = c[FLOW_IN].bundle->channel_ports (c[FLOW_IN].channel);
+ Bundle::PortList const & out_ports = c[FLOW_OUT].bundle->channel_ports (c[FLOW_OUT].channel);
if (in_ports.empty() || out_ports.empty()) {
/* we're looking at a bundle with no parts associated with this channel,
so nothing to connect */
private:
/* see PortMatrix: signal flow from 0 to 1 (out to in) */
enum {
- OUT = 0,
- IN = 1,
+ FLOW_OUT = 0,
+ FLOW_IN = 1,
};
};
#include "pbd/file_utils.h"
#include "pbd/textreceiver.h"
#include "pbd/failed_constructor.h"
+#include "pbd/pathexpand.h"
#include "pbd/pthread_utils.h"
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
#include "pbd/boost_debug.h"
static void export_search_path (const string& base_dir, const char* varname, const char* dir)
{
string path;
- const char * cstr = getenv (varname);
+ const char * cstr = g_getenv (varname);
if (cstr) {
path = cstr;
path += base_dir;
path += dir;
- setenv (varname, path.c_str(), 1);
+ g_setenv (varname, path.c_str(), 1);
}
#ifdef __APPLE__
void
fixup_bundle_environment (int, char* [])
{
- if (!getenv ("ARDOUR_BUNDLED")) {
+ if (!g_getenv ("ARDOUR_BUNDLED")) {
return;
}
export_search_path (bundle_dir, "VAMP_PATH", "/lib");
export_search_path (bundle_dir, "GTK_PATH", "/lib/gtkengines");
- setenv ("SUIL_MODULE_DIR", (bundle_dir + "/lib").c_str(), 1);
- setenv ("PATH", (bundle_dir + "/MacOS:" + std::string(getenv ("PATH"))).c_str(), 1);
+ g_setenv ("SUIL_MODULE_DIR", (bundle_dir + "/lib").c_str(), 1);
+ g_setenv ("PATH", (bundle_dir + "/MacOS:" + std::string(g_getenv ("PATH"))).c_str(), 1);
/* unset GTK_RC_FILES so that we only load the RC files that we define
*/
- unsetenv ("GTK_RC_FILES");
+ g_unsetenv ("GTK_RC_FILES");
/* write a pango.rc file and tell pango to use it. we'd love
to put this into the PROGRAM_NAME.app bundle and leave it there,
<< endl;
pangorc.close ();
- setenv ("PANGO_RC_FILE", path.c_str(), 1);
+ g_setenv ("PANGO_RC_FILE", path.c_str(), 1);
}
}
- setenv ("CHARSETALIASDIR", bundle_dir.c_str(), 1);
- setenv ("FONTCONFIG_FILE", Glib::build_filename (bundle_dir, "Resources/fonts.conf").c_str(), 1);
- setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (bundle_dir, "Resources/gdk-pixbuf.loaders").c_str(), 1);
+ g_setenv ("CHARSETALIASDIR", bundle_dir.c_str(), 1);
+ g_setenv ("FONTCONFIG_FILE", Glib::build_filename (bundle_dir, "Resources/fonts.conf").c_str(), 1);
+ g_setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (bundle_dir, "Resources/gdk-pixbuf.loaders").c_str(), 1);
}
static void load_custom_fonts() {
* acceptable to build paths directly using '/'.
*/
- if (!getenv ("ARDOUR_BUNDLED")) {
+ if (!g_getenv ("ARDOUR_BUNDLED")) {
return;
}
lpath.push_back (dir_path);
lpath.push_back ("share");
lpath.push_back ("locale");
- localedir = realpath (Glib::build_filename (lpath).c_str(), NULL);
+ localedir = canonical_path (Glib::build_filename (lpath)).c_str();
}
#endif
export_search_path (dir_path, "VAMP_PATH", "/lib");
export_search_path (dir_path, "GTK_PATH", "/lib/gtkengines");
- setenv ("SUIL_MODULE_DIR", (dir_path + "/lib").c_str(), 1);
- setenv ("PATH", (dir_path + "/bin:" + std::string(getenv ("PATH"))).c_str(), 1);
+ g_setenv ("SUIL_MODULE_DIR", (dir_path + "/lib").c_str(), 1);
+ g_setenv ("PATH", (dir_path + "/bin:" + std::string(g_getenv ("PATH"))).c_str(), 1);
/* unset GTK_RC_FILES so that we only load the RC files that we define
*/
- unsetenv ("GTK_RC_FILES");
+ g_unsetenv ("GTK_RC_FILES");
/* Tell fontconfig where to find fonts.conf. Use the system version
if it exists, otherwise use the stuff we included in the bundle
*/
if (Glib::file_test ("/etc/fonts/fonts.conf", Glib::FILE_TEST_EXISTS)) {
- setenv ("FONTCONFIG_FILE", "/etc/fonts/fonts.conf", 1);
- setenv ("FONTCONFIG_PATH", "/etc/fonts", 1);
+ g_setenv ("FONTCONFIG_FILE", "/etc/fonts/fonts.conf", 1);
+ g_setenv ("FONTCONFIG_PATH", "/etc/fonts", 1);
} else {
error << _("No fontconfig file found on your system. Things may looked very odd or ugly") << endmsg;
}
pangorc.close ();
}
- setenv ("PANGO_RC_FILE", path.c_str(), 1);
+ g_setenv ("PANGO_RC_FILE", path.c_str(), 1);
/* similar for GDK pixbuf loaders, but there's no RC file required
to specify where it lives.
*/
- setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (userconfigdir, "gdk-pixbuf.loaders").c_str(), 1);
+ g_setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (userconfigdir, "gdk-pixbuf.loaders").c_str(), 1);
}
/* this doesn't do much but setting it should prevent various parts of the GTK/GNU stack
from looking outside the bundle to find the charset.alias file.
*/
- setenv ("CHARSETALIASDIR", dir_path.c_str(), 1);
+ g_setenv ("CHARSETALIASDIR", dir_path.c_str(), 1);
}
text_receiver.listen_to (warning);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
- if (getenv ("BOOST_DEBUG")) {
+ if (g_getenv ("BOOST_DEBUG")) {
boost_debug_shared_ptr_show_live_debugging (true);
}
#endif
return curvetest (curvetest_file);
}
+#ifndef WIN32
if (::signal (SIGPIPE, sigpipe_handler)) {
cerr << _("Cannot xinstall SIGPIPE error handler") << endl;
}
+#endif
try {
ui = new ARDOUR_UI (&argc, &argv, localedir);
MenuList& ops_items = ops_menu->items();
ops_items.push_back (SeparatorElem ());
ops_items.push_back (CheckMenuElem (_("Display delta to edit cursor"), sigc::mem_fun (*this, &MainClock::display_delta_to_edit_cursor)));
- CheckMenuItem* c = dynamic_cast<CheckMenuItem *> (&ops_items.back());
+ Gtk::CheckMenuItem* c = dynamic_cast<Gtk::CheckMenuItem *> (&ops_items.back());
if (_primary) {
if (ARDOUR::Config->get_primary_clock_delta_edit_cursor ()) {
ARDOUR::Config->set_primary_clock_delta_edit_cursor (false);
/* adjust to properly locate the tip */
- mark = new Polygon (*group);
+ mark = new ArdourCanvas::Polygon (*group);
mark->property_points() = *points;
set_color_rgba (rgba);
mark->property_width_pixels() = 1;
case ForceChannel:
/* only set the lowest set channel in the mask as active */
for (uint16_t i = 0; i < 16; i++) {
- playback_buttons[i]->set_active (i == (ffs (mask) - 1));
+ playback_buttons[i]->set_active (i == (PBD::ffs (mask) - 1));
}
break;
}
case ForceChannel:
/* only set the lowest set channel in the mask as active */
for (uint16_t i = 0; i < 16; i++) {
- capture_buttons[i]->set_active (i == (ffs (mask) - 1));
+ capture_buttons[i]->set_active (i == (PBD::ffs (mask) - 1));
}
break;
}
case ForceChannel:
if (last_drawn_playback_mode == AllChannels || last_drawn_playback_mode == FilterChannels) {
playback_buttons.clear ();
- first_channel = ffs (track->get_playback_channel_mask()) - 1;
+ first_channel = PBD::ffs (track->get_playback_channel_mask()) - 1;
}
for (vector<Widget*>::iterator i = playback_mask_controls.begin(); i != playback_mask_controls.end(); ++i) {
(*i)->set_sensitive (false);
case ForceChannel:
if (last_drawn_capture_mode == AllChannels || last_drawn_capture_mode == FilterChannels) {
capture_buttons.clear ();
- first_channel = ffs (track->get_capture_channel_mask()) - 1;
+ first_channel = PBD::ffs (track->get_capture_channel_mask()) - 1;
}
for (vector<Widget*>::iterator i = capture_mask_controls.begin(); i != capture_mask_controls.end(); ++i) {
(*i)->set_sensitive (false);
#include <string>
#include <vector>
+#ifdef interface
+#undef interface
+#endif
+
#include <libgnomecanvasmm.h>
#include <libgnomecanvasmm/polygon.h>
#include <cstdlib>
#include <cmath>
-#include <strings.h> // for ffs(3)
-
#include <algorithm>
#include <string>
#include <vector>
#include <sigc++/bind.h>
#include "pbd/error.h"
+#include "pbd/ffs.h"
#include "pbd/stl_delete.h"
#include "pbd/whitespace.h"
#include "pbd/basename.h"
}
}
- CheckMenuItem* cmi = static_cast<CheckMenuItem*>(&chn_items.back());
+ Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*>(&chn_items.back());
_channel_command_menu_map[fully_qualified_param] = cmi;
cmi->set_active (visible);
}
}
}
- CheckMenuItem* cmi = static_cast<CheckMenuItem*>(&items.back());
+ Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*>(&items.back());
_channel_command_menu_map[fully_qualified_param] = cmi;
cmi->set_active (visible);
}
}
- CheckMenuItem* cmi = static_cast<CheckMenuItem*>(&ctl_items.back());
+ Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*>(&ctl_items.back());
_controller_menu_map[fully_qualified_param] = cmi;
cmi->set_active (visible);
}
}
- CheckMenuItem* cmi = static_cast<CheckMenuItem*>(&chn_items.back());
+ Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*>(&chn_items.back());
_controller_menu_map[fully_qualified_param] = cmi;
cmi->set_active (visible);
}
_playback_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2</i>", _("Play"), _("some")));
break;
case ForceChannel:
- _playback_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2>%3</i>", _("Play"), _("all"), ffs (midi_track()->get_playback_channel_mask())));
+ _playback_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2>%3</i>", _("Play"), _("all"), PBD::ffs (midi_track()->get_playback_channel_mask())));
break;
}
}
_capture_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2</i>", _("Rec"), _("some")));
break;
case ForceChannel:
- _capture_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2>%3</i>", _("Rec"), _("all"), ffs (midi_track()->get_capture_channel_mask())));
+ _capture_channel_status.set_markup (string_compose ("<b>%1</b>: <i>%2>%3</i>", _("Rec"), _("all"), PBD::ffs (midi_track()->get_capture_channel_mask())));
break;
}
}
#include <sys/time.h>
#include <time.h>
+#include "pbd/localtime_r.h"
+#include "pbd/timersub.h"
+
#include "midi++/parser.h"
#include "ardour/async_midi_port.h"
#include "pbd/compose.h"
#include "pbd/replace_all.h"
#include "pbd/strsplit.h"
+#include "pbd/search_path.h"
#include "ardour/session.h"
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);
items.push_back (SeparatorElem());
items.push_back (CheckMenuElem (_("Active")));
- CheckMenuItem* i = dynamic_cast<CheckMenuItem *> (&items.back());
+ Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
i->set_active (_route->active());
i->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::set_route_active), !_route->active(), false));
items.push_back (SeparatorElem());
items.push_back (CheckMenuElem (_("Protect Against Denormals"), sigc::mem_fun (*this, &RouteUI::toggle_denormal_protection)));
- denormal_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
+ denormal_menu_item = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
denormal_menu_item->set_active (_route->denormal_protection());
if (!Profile->get_sae()) {
{
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());
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);
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);
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);
cairo_fill (cr);
cairo_restore (cr);
- if (!small) {
+ if (!small_size) {
cairo_set_font_size (cr, 16);
/* move the text in just a bit */
items.clear ();
items.push_back (CheckMenuElem (_("Bypass"), sigc::mem_fun(*this, &PannerUI::pan_bypass_toggle)));
- bypass_menu_item = static_cast<CheckMenuItem*> (&items.back());
+ bypass_menu_item = static_cast<Gtk::CheckMenuItem*> (&items.back());
/* set state first, connect second */
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);
#include <fstream>
#include <cstring>
+#ifndef WIN32
#include <sys/utsname.h>
+#endif
+
#include <curl/curl.h>
#include <glibmm/miscutils.h>
static void*
_pingback (void *arg)
{
+#ifndef WIN32
ping_call* cm = static_cast<ping_call*> (arg);
CURL* c;
struct utsname utb;
curl_easy_cleanup (c);
delete cm;
+#endif /* WIN32 */
+
return 0;
}
#endif
#include <cstdio>
-#include <lrdf.h>
#include <map>
#include <algorithm>
#include "lv2_plugin_ui.h"
#endif
-#include <lrdf.h>
-
#include "ardour_window.h"
#include "ardour_ui.h"
#include "prompter.h"
items.push_back (MenuElem (_("Rescan"), sigc::mem_fun (*this, &PortMatrix::setup_all_ports)));
items.push_back (CheckMenuElem (_("Show individual ports"), sigc::mem_fun (*this, &PortMatrix::toggle_show_only_bundles)));
- CheckMenuItem* i = dynamic_cast<CheckMenuItem*> (&items.back());
+ Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem*> (&items.back());
_inhibit_toggle_show_only_bundles = true;
i->set_active (!_show_only_bundles);
_inhibit_toggle_show_only_bundles = false;
for (list<Control*>::iterator i = _controls.begin(); i != _controls.end(); ++i) {
items.push_back (CheckMenuElem ((*i)->name ()));
- CheckMenuItem* c = dynamic_cast<CheckMenuItem*> (&items.back ());
+ Gtk::CheckMenuItem* c = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
c->set_active ((*i)->visible ());
c->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ProcessorEntry::toggle_control_visibility), *i));
}
#include "ardour/ardour.h"
+#ifdef interface
+#undef interface
+#endif
+
#include <libgnomecanvasmm.h>
#include "automation_line.h"
#ifndef __gtk_ardour_region_view_h__
#define __gtk_ardour_region_view_h__
+#ifdef interface
+#undef interface
+#endif
+
#include <vector>
#include <libgnomecanvasmm.h>
}
items.push_back (CheckMenuElem (_("Active")));
- CheckMenuItem* i = dynamic_cast<CheckMenuItem *> (&items.back());
+ Gtk::CheckMenuItem* i = dynamic_cast<Gtk::CheckMenuItem *> (&items.back());
bool click_sets_active = true;
if (active > 0 && inactive == 0) {
i->set_active (true);
for (std::set<Evoral::Parameter>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
ProcessorAutomationNode* pan;
- CheckMenuItem* mitem;
+ Gtk::CheckMenuItem* mitem;
string name = processor->describe_parameter (*i);
items.push_back (CheckMenuElem (name));
- mitem = dynamic_cast<CheckMenuItem*> (&items.back());
+ mitem = dynamic_cast<Gtk::CheckMenuItem*> (&items.back());
_subplugin_menu_map[*i] = mitem;
MenuList& items = record_menu->items();
items.push_back (CheckMenuElem (_("Step Entry"), sigc::mem_fun (*this, &RouteUI::toggle_step_edit)));
- step_edit_item = dynamic_cast<CheckMenuItem*> (&items.back());
+ step_edit_item = dynamic_cast<Gtk::CheckMenuItem*> (&items.back());
if (_route->record_enabled()) {
step_edit_item->set_sensitive (false);
solo_menu = new Menu;
solo_menu->set_name ("ArdourContextMenu");
MenuList& items = solo_menu->items();
- CheckMenuItem* check;
+ Gtk::CheckMenuItem* check;
- check = new CheckMenuItem(_("Solo Isolate"));
+ check = new Gtk::CheckMenuItem(_("Solo Isolate"));
check->set_active (_route->solo_isolated());
check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_isolated), check));
items.push_back (CheckMenuElem(*check));
- solo_isolated_check = dynamic_cast<CheckMenuItem*>(&items.back());
+ solo_isolated_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
check->show_all();
- check = new CheckMenuItem(_("Solo Safe"));
+ check = new Gtk::CheckMenuItem(_("Solo Safe"));
check->set_active (_route->solo_safe());
check->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_solo_safe), check));
items.push_back (CheckMenuElem(*check));
- solo_safe_check = dynamic_cast<CheckMenuItem*>(&items.back());
+ solo_safe_check = dynamic_cast<Gtk::CheckMenuItem*>(&items.back());
check->show_all();
//items.push_back (SeparatorElem());
MenuList& items = mute_menu->items();
- pre_fader_mute_check = manage (new CheckMenuItem(_("Pre Fader")));
+ pre_fader_mute_check = manage (new Gtk::CheckMenuItem(_("Pre Fader")));
init_mute_menu(MuteMaster::PreFader, pre_fader_mute_check);
pre_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PreFader, pre_fader_mute_check));
items.push_back (CheckMenuElem(*pre_fader_mute_check));
pre_fader_mute_check->show_all();
- post_fader_mute_check = manage (new CheckMenuItem(_("Post Fader")));
+ post_fader_mute_check = manage (new Gtk::CheckMenuItem(_("Post Fader")));
init_mute_menu(MuteMaster::PostFader, post_fader_mute_check);
post_fader_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::PostFader, post_fader_mute_check));
items.push_back (CheckMenuElem(*post_fader_mute_check));
post_fader_mute_check->show_all();
- listen_mute_check = manage (new CheckMenuItem(_("Control Outs")));
+ listen_mute_check = manage (new Gtk::CheckMenuItem(_("Control Outs")));
init_mute_menu(MuteMaster::Listen, listen_mute_check);
listen_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::Listen, listen_mute_check));
items.push_back (CheckMenuElem(*listen_mute_check));
listen_mute_check->show_all();
- main_mute_check = manage (new CheckMenuItem(_("Main Outs")));
+ main_mute_check = manage (new Gtk::CheckMenuItem(_("Main Outs")));
init_mute_menu(MuteMaster::Main, main_mute_check);
main_mute_check->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteUI::toggle_mute_menu), MuteMaster::Main, main_mute_check));
items.push_back (CheckMenuElem(*main_mute_check));
}
void
-RouteUI::init_mute_menu(MuteMaster::MutePoint mp, CheckMenuItem* check)
+RouteUI::init_mute_menu(MuteMaster::MutePoint mp, Gtk::CheckMenuItem* check)
{
check->set_active (_route->mute_points() & mp);
}
for (uint32_t i = 0; i < N; ++i) {
items.push_back (CheckMenuElem (string_compose (X_("Ø%1"), i + 1), sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_menu_toggled), i)));
- CheckMenuItem* e = dynamic_cast<CheckMenuItem*> (&items.back ());
+ Gtk::CheckMenuItem* e = dynamic_cast<Gtk::CheckMenuItem*> (&items.back ());
++_i_am_the_modifier;
e->set_active (_route->phase_invert (i));
--_i_am_the_modifier;
#include "ardour_dialog.h"
+#ifdef interface
+#undef interface
+#endif
+
#include <gtkmm.h>
#include <boost/shared_ptr.hpp>
Gtk::Label* value_label;
Gtk::Entry* entry;
- uint width;
+ guint width;
};
/// MetadataField that accepts only numbers
#include <gtkmm/box.h>
#include <gtkmm/stock.h>
+
+#include <glib/gstdio.h>
#include <glibmm/fileutils.h>
#include "pbd/convert.h"
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;
goto out;
}
- unlink (tmpc);
+ ::g_unlink (tmpc);
}
ret = true;
out:
rmdir (tmpdir.c_str());
return ret;
+#endif
}
SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s)
#endif
std::string ff_file_path;
- if (find_file_in_search_path (SearchPath(Glib::getenv("PATH")), X_("ffmpeg_harvid"), ff_file_path)) { ffmpeg_exe = ff_file_path; }
+ if (find_file_in_search_path (Searchpath(Glib::getenv("PATH")), X_("ffmpeg_harvid"), ff_file_path)) { ffmpeg_exe = ff_file_path; }
else if (Glib::file_test(X_("C:\\Program Files\\harvid\\ffmpeg.exe"), Glib::FILE_TEST_EXISTS)) {
ffmpeg_exe = X_("C:\\Program Files\\ffmpeg\\ffmpeg.exe");
}
ffmpeg_exe = X_("C:\\Program Files\\ffmpeg\\ffmpeg.exe");
}
- if (find_file_in_search_path (SearchPath(Glib::getenv("PATH")), X_("ffprobe_harvid"), ff_file_path)) { ffprobe_exe = ff_file_path; }
+ if (find_file_in_search_path (Searchpath(Glib::getenv("PATH")), X_("ffprobe_harvid"), ff_file_path)) { ffprobe_exe = ff_file_path; }
else if (Glib::file_test(X_("C:\\Program Files\\harvid\\ffprobe.exe"), Glib::FILE_TEST_EXISTS)) {
ffprobe_exe = X_("C:\\Program Files\\ffmpeg\\ffprobe.exe");
}
* SystemExec::Terminated is emitted and ffcmd set to NULL */
int timeout = 300; // 1.5 sec
while (ffcmd && --timeout > 0) {
- usleep(5000);
+ Glib::usleep(5000);
}
if (timeout == 0 || ffoutput.empty()) {
return false;
{
if (!ffcmd || !ffcmd->is_running()) { return;}
ffcmd->write_to_stdin("q");
+#ifdef WIN32
+ Sleep(1000);
+#else
sleep (1);
+#endif
if (ffcmd) {
ffcmd->terminate();
}
#include <sigc++/bind.h>
+#include <glib/gstdio.h>
+
#include "pbd/error.h"
#include "pbd/convert.h"
#include "gtkmm2ext/utils.h"
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 {
}
// cerr << string_compose (_("Color %1 not found"), name) << endl;
- return RGBA_TO_UINT (random()%256,random()%256,random()%256,0xff);
+ return RGBA_TO_UINT (g_random_int()%256,g_random_int()%256,g_random_int()%256,0xff);
}
void
{
if (!xpm_map[name]) {
- SearchPath spath(ARDOUR::ardour_data_search_path());
+ Searchpath spath(ARDOUR::ardour_data_search_path());
spath.add_subdirectory_to_paths("pixmaps");
string name = cname;
name += X_(".png");
- SearchPath spath(ARDOUR::ardour_data_search_path());
+ Searchpath spath(ARDOUR::ardour_data_search_path());
spath.add_subdirectory_to_paths("icons");
/* 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 */
const int32_t max_saturation = 48000; // 65535 would open up the whole color wheel
- newcolor.set_red (random() % max_saturation);
- newcolor.set_blue (random() % max_saturation);
- newcolor.set_green (random() % max_saturation);
+ newcolor.set_red (g_random_int() % max_saturation);
+ newcolor.set_blue (g_random_int() % max_saturation);
+ newcolor.set_green (g_random_int() % max_saturation);
if (used_colors.size() == 0) {
used_colors.push_back (newcolor);
char *res = NULL;
do {
res=a3_curl_http_get(url, &status);
- if (status == 503) usleep(5000); // try-again
+ if (status == 503) Glib::usleep(5000); // try-again
} while (status == 503 && --timeout > 0);
if (status != 200 || !res) {
exposeimg();
/* don't request frames too quickly, wait after user has zoomed */
- usleep(40000);
+ Glib::usleep(40000);
if (queued_request) {
http_get_again(want_video_frame_number);
process->write_to_stdin("get osdcfg\n");
int timeout = 40;
if (wait && knownstate !=127 && --timeout) {
- usleep(50000);
+ Glib::usleep(50000);
sched_yield();
}
}
*/
int timeout = 40;
while (is_started() && --timeout) {
- usleep(50000);
+ Glib::usleep(50000);
sched_yield();
}
if (timeout <= 0) {
#include "ardour/template_utils.h"
#include "ardour/session.h"
+#ifdef interface
+#undef interface
+#endif
+
#include "video_server_dialog.h"
#include "utils_videotl.h"
#include "i18n.h"
listenaddr_combo.set_active(0);
std::string icsd_file_path;
- if (find_file_in_search_path (PBD::SearchPath(Glib::getenv("PATH")), X_("harvid"), icsd_file_path)) {
+ if (find_file_in_search_path (PBD::Searchpath(Glib::getenv("PATH")), X_("harvid"), icsd_file_path)) {
path_entry.set_text(icsd_file_path);
}
else if (Glib::file_test(X_("C:\\Program Files\\harvid\\harvid.exe"), Glib::FILE_TEST_EXISTS)) {
std::string xjadeo_file_path;
if (getenv("XJREMOTE")) {
_xjadeo_bin = strdup(getenv("XJREMOTE")); // XXX TODO: free it?!
- } else if (find_file_in_search_path (SearchPath(Glib::getenv("PATH")), X_("xjremote"), xjadeo_file_path)) {
+ } else if (find_file_in_search_path (Searchpath(Glib::getenv("PATH")), X_("xjremote"), xjadeo_file_path)) {
_xjadeo_bin = xjadeo_file_path;
}
else if (Glib::file_test(X_("/Applications/Jadeo.app/Contents/MacOS/xjremote"), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) {
'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
'libmidipp',
'ardour',
'libardour_cp',
- 'libgtkmm2ext']
+ 'libgtkmm2ext',
+ ]
+
+ if bld.env['build_target'] == 'mingw':
+ if bld.env['DEBUG'] == False:
+ obj.linkflags = ['-mwindows']
+
if bld.is_defined('USE_EXTERNAL_LIBS'):
obj.uselib += ' TAGLIB'
else:
obj.use.append('libtaglib')
+
if sys.platform == 'darwin':
obj.use += ' libappleutility'
obj.defines = [
/* called from non-RT context */
void parse (framecnt_t timestamp);
- int write (const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp);
+ int write (const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp);
int read (MIDI::byte *buf, size_t bufsize);
void drain (int check_interval_usecs);
- int selectable () const { return xthread.selectable(); }
+ int selectable () const {
+#ifdef PLATFORM_WINDOWS
+ return false;
+#else
+ return xthread.selectable();
+#endif
+ }
static void set_process_thread (pthread_t);
static pthread_t get_process_thread () { return _process_thread; }
MIDI::timestamp_t _last_write_timestamp;
RingBuffer< Evoral::Event<double> > output_fifo;
Evoral::EventRingBuffer<MIDI::timestamp_t> input_fifo;
- Glib::Threads::Mutex output_fifo_lock;
- CrossThreadChannel xthread;
+ Glib::Threads::Mutex output_fifo_lock;
+#ifndef PLATFORM_WINDOWS
+ CrossThreadChannel xthread;
+#endif
+
+ int create_port ();
+
+ /** Channel used to signal to the MidiControlUI that input has arrived */
+
+ std::string _connections;
+ PBD::ScopedConnection connect_connection;
+ PBD::ScopedConnection halt_connection;
+ void flush (void* jack_port_buffer);
+ void jack_halted ();
+ void make_connections ();
+ void init (std::string const &, Flags);
void flush_output_fifo (pframes_t);
virtual void clear_capture_marks() {}
virtual bool one_of_several_channels () const { return false; }
+ virtual void flush () = 0;
virtual int update_header (framepos_t when, struct tm&, time_t) = 0;
virtual int flush_header () = 0;
namespace ARDOUR {
class Session;
-class Region;
class AudioRegion;
class Source;
* contain the user and system directories which may contain audio/MIDI
* backends.
*/
- PBD::SearchPath backend_search_path ();
+ PBD::Searchpath backend_search_path ();
} // namespace ARDOUR
#ifndef __ardour_butler_h__
#define __ardour_butler_h__
+#include <pthread.h>
+
#include <glibmm/threads.h>
+#ifdef PLATFORM_WINDOWS
+#include "pbd/glib_semaphore.h"
+#endif
+
#include "pbd/ringbuffer.h"
#include "pbd/pool.h"
#include "ardour/types.h"
#include "ardour/session_handle.h"
+
+
namespace ARDOUR {
/**
Glib::Threads::Cond paused;
bool should_run;
mutable gint should_do_transport_work;
- int request_pipe[2];
framecnt_t audio_dstream_capture_buffer_size;
framecnt_t audio_dstream_playback_buffer_size;
uint32_t midi_dstream_buffer_size;
RingBuffer<CrossThreadPool*> pool_trash;
+#ifdef PLATFORM_WINDOWS
+ PBD::atomic_counter m_request_state;
+ PBD::GlibSemaphore m_request_sem;
+#else
+ int request_pipe[2];
+#endif
+
private:
void empty_pool_trash ();
void config_changed (std::string);
+
+#ifndef PLATFORM_WINDOWS
+ int setup_request_pipe ();
+#endif
+
+ /**
+ * return true if there are requests to be processed
+ */
+ bool wait_for_requests ();
+
+ /**
+ * Remove request from butler request queue
+ *
+ * return true if there was another request and req is valid
+ */
+ bool dequeue_request (Request::Type& req);
+
+ /**
+ * Add request to butler thread request queue
+ */
+ void queue_request (Request::Type r);
+
};
} // namespace ARDOUR
#include "pbd/xml++.h"
#include "ardour/data_type.h"
+#ifdef INFINITE
+#undef INFINITE
+#endif
+
namespace ARDOUR {
namespace ARDOUR {
/**
- * return a SearchPath containing directories in which to look for
+ * return a Searchpath containing directories in which to look for
* control surface plugins.
*
- * If ARDOUR_SURFACES_PATH is defined then the SearchPath returned
+ * If ARDOUR_SURFACES_PATH is defined then the Searchpath returned
* will contain only those directories specified in it, otherwise it will
* contain the user and system directories which may contain control
* surface plugins.
*/
- PBD::SearchPath control_protocol_search_path ();
+ PBD::Searchpath control_protocol_search_path ();
} // namespace ARDOUR
void set_header_timeline_position () {};
bool clamped_at_unity () const { return false; }
+ void flush () {}
+
static int get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg);
protected:
/* debian: sparc, arm, m68k */
+#ifndef COMPILER_MSVC
+/* GRRR... Annoyingly, #warning aborts the compilation for MSVC !! */
#warning You are compiling libardour on a platform for which ardour/cycles.h needs work
+#endif
#include <sys/time.h>
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;
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;
extern const char* const backend_dir_name;
namespace ARDOUR {
/**
- * return a SearchPath containing directories in which to look for
+ * return a Searchpath containing directories in which to look for
* export_formats.
*/
- PBD::SearchPath export_formats_search_path ();
+ PBD::Searchpath export_formats_search_path ();
} // namespace ARDOUR
std::vector<std::string> find_file (std::string const & pattern);
std::string export_config_dir;
- PBD::SearchPath search_path;
+ PBD::Searchpath search_path;
/* Timespans */
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,
* @return the search path to be used when looking for per-system
* configuration files. This may include user configuration files.
*/
- PBD::SearchPath ardour_config_search_path ();
+ PBD::Searchpath ardour_config_search_path ();
/**
* @return the search path to be used when looking for data files
* that could be shared by systems (h/w and configuration independent
* files, such as icons, XML files, etc)
*/
- PBD::SearchPath ardour_data_search_path ();
+ PBD::Searchpath ardour_data_search_path ();
} // namespace ARDOUR
class InterThreadInfo {
public:
- InterThreadInfo () : done (false), cancel (false), progress (0), thread (0) {}
+ InterThreadInfo () : done (false), cancel (false), progress (0), thread () {}
volatile bool done;
volatile bool cancel;
--- /dev/null
+/*
+ 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);
+}
#include <set>
#include <vector>
#include <string>
-#include <dlfcn.h>
+#include <glibmm/module.h>
#include "pbd/stateful.h"
class LadspaPlugin : public ARDOUR::Plugin
{
public:
- LadspaPlugin (void *module, ARDOUR::AudioEngine&, ARDOUR::Session&, uint32_t index, framecnt_t sample_rate);
+ LadspaPlugin (std::string module_path, ARDOUR::AudioEngine&, ARDOUR::Session&, uint32_t index, framecnt_t sample_rate);
LadspaPlugin (const LadspaPlugin &);
~LadspaPlugin ();
void connect_port (uint32_t port, float *ptr) { _descriptor->connect_port (_handle, port, ptr); }
private:
- void* _module;
+ std::string _module_path;
+ Glib::Module* _module;
const LADSPA_Descriptor* _descriptor;
LADSPA_Handle _handle;
framecnt_t _sample_rate;
void find_presets ();
- void init (void *mod, uint32_t index, framecnt_t rate);
+ void init (std::string module_path, uint32_t index, framecnt_t rate);
void run_in_place (pframes_t nsamples);
void latency_compute_run ();
int set_state_2X (const XMLNode&, int version);
--- /dev/null
+/*
+ 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
namespace ARDOUR {
/**
- * return a SearchPath containing directories in which to look for
+ * return a Searchpath containing directories in which to look for
* lv2 plugins.
*/
- PBD::SearchPath lv2_bundled_search_path ();
+ PBD::Searchpath lv2_bundled_search_path ();
} // namespace ARDOUR
#include "ardour/worker.h"
#include "pbd/ringbuffer.h"
+typedef struct LV2_Evbuf_Impl LV2_Evbuf;
+
namespace ARDOUR {
// a callback function for lilv_state_new_from_instance(). friend of LV2Plugin
namespace ARDOUR {
/**
- * return a SearchPath containing directories in which to look for
+ * return a Searchpath containing directories in which to look for
* MIDI patch files ("*.midnam") aka MIDNAM files
*
- * If ARDOUR_MIDI_PATCH_PATH is defined then the SearchPath returned
+ * If ARDOUR_MIDI_PATCH_PATH is defined then the Searchpath returned
* will contain only those directories specified in it, otherwise it will
* contain the user and system directories which may contain control
* surface plugins.
*/
- PBD::SearchPath midi_patch_search_path ();
+ PBD::Searchpath midi_patch_search_path ();
} // namespace ARDOUR
{
class Session;
-class Region;
class MidiRegion;
class Source;
template<typename T> class MidiRingBuffer;
#ifndef __ardour_midi_track_h__
#define __ardour_midi_track_h__
+#include "pbd/ffs.h"
+
#include "ardour/track.h"
#include "ardour/midi_ring_buffer.h"
/* if mode is ForceChannel, force mask to the lowest set channel or 1 if no
* channels are set.
*/
-#define force_mask(mode,mask) (((mode) == ForceChannel) ? (((mask) ? (1<<(ffs((mask))-1)) : 1)) : mask)
+#define force_mask(mode,mask) (((mode) == ForceChannel) ? (((mask) ? (1<<(PBD::ffs((mask))-1)) : 1)) : mask)
void _set_playback_channel_mode(ChannelMode mode, uint16_t mask) {
mask = force_mask (mode, mask);
--- /dev/null
+/*
+ Copyright (C) 2009 John Emmas
+
+ 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 __msvc_libardour_h__
+#define __msvc_libardour_h__
+
+#include "ardour/visibility.h"
+#include <limits.h>
+
+#ifndef _MAX_PATH
+#define _MAX_PATH 260
+#endif
+#ifndef PATH_MAX
+#define PATH_MAX _MAX_PATH
+#endif
+
+namespace ARDOUR {
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+// LIBARDOUR_API char* LIBARDOUR_APICALLTYPE placeholder_for_non_msvc_specific_function(s);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+} // namespace ARDOUR
+
+#ifdef COMPILER_MSVC
+#include <rpc.h>
+//#include <io.h>
+
+#ifndef __THROW
+#define __THROW throw()
+#endif
+#include <ardourext/sys/time.h>
+
+namespace ARDOUR {
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+LIBARDOUR_API int LIBARDOUR_APICALLTYPE symlink(const char *dest, const char *shortcut, const char *working_directory = 0);
+LIBARDOUR_API int LIBARDOUR_APICALLTYPE readlink(const char *__restrict shortcut, char *__restrict buf, size_t bufsize);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+} // namespace ARDOUR
+
+#endif // COMPILER_MSVC
+#endif // __mavc_libardour_h__
#include "ardour/types.h"
#include "ardour/automation_control.h"
#include "ardour/automatable.h"
+#include "ardour/visibility.h"
+
+#ifdef ARDOURPANNER_DLL_EXPORTS // defined if we are building the ARDOUR Panners DLLs (instead of using them)
+ #define ARDOURPANNER_API LIBARDOUR_HELPER_DLL_EXPORT
+#else
+ #define ARDOURPANNER_API LIBARDOUR_HELPER_DLL_IMPORT
+#endif
+#define ARDOURPANNER_LOCAL LIBARDOUR_HELPER_DLL_LOCAL
namespace ARDOUR {
#ifndef __ardour_panner_manager_h__
#define __ardour_panner_manager_h__
-#include <dlfcn.h>
+#include <glibmm/module.h>
+
#include "ardour/panner.h"
#include "ardour/session_handle.h"
struct PannerInfo {
PanPluginDescriptor descriptor;
- void* module;
+ Glib::Module* module;
- PannerInfo (PanPluginDescriptor& d, void* handle)
+ PannerInfo (PanPluginDescriptor& d, Glib::Module* m)
: descriptor (d)
- , module (handle)
+ , module (m)
{}
~PannerInfo () {
- dlclose (module);
+ delete module;
}
};
namespace ARDOUR {
/**
- * return a SearchPath containing directories in which to look for
+ * return a Searchpath containing directories in which to look for
* panner plugins.
*
- * If ARDOUR_PANNER_PATH is defined then the SearchPath returned
+ * If ARDOUR_PANNER_PATH is defined then the Searchpath returned
* will contain only those directories specified in it, otherwise it will
* contain the user and system directories which may contain control
* surface plugins.
*/
- PBD::SearchPath panner_search_path ();
+ PBD::Searchpath panner_search_path ();
} // namespace ARDOUR
#include "evoral/types.hpp"
#include "ardour/ardour.h"
+#include "ardour/region.h"
#include "ardour/session_object.h"
#include "ardour/data_type.h"
namespace ARDOUR {
class Session;
-class Region;
class Playlist;
class Crossfade;
void refresh ();
- int add_ladspa_directory (std::string dirpath);
int add_windows_vst_directory (std::string dirpath);
int add_lxvst_directory (std::string dirpath);
std::map<uint32_t, std::string> rdf_type;
- std::string ladspa_path;
std::string windows_vst_path;
std::string lxvst_path;
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);
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;
#include "pbd/ringbuffer.h"
#include "pbd/event_loop.h"
+#include "ardour/visibility.h"
#include "ardour/types.h"
namespace ARDOUR {
class Slave;
class Region;
-class SessionEvent {
+class LIBARDOUR_API SessionEvent {
public:
enum Type {
SetTransportSpeed,
friend class Butler;
};
-class SessionEventManager {
+class LIBARDOUR_API SessionEventManager {
public:
SessionEventManager () : pending_events (2048),
auto_loop_event(0), punch_out_event(0), punch_in_event(0) {}
float sample_rate () const { return _sample_rate; }
void set_length (framecnt_t len) { _length = len; }
+ void flush () {}
bool destructive() const { return false; }
bool can_be_analysed() const { return false; }
float sample_rate () const;
int update_header (framepos_t when, struct tm&, time_t);
int flush_header ();
+ void flush ();
framepos_t natural_position () const;
#ifndef __libardour_visibility_h__
#define __libardour_visibility_h__
+#ifdef LIBARDOUR_IS_IN_WIN_STATIC_LIB // #define if your project uses libardour (under Windows) as a static library
+#define LIBARDOUR_IS_IN_WINDLL 0
+#endif
+
+#if !defined(LIBARDOUR_IS_IN_WINDLL)
+ #if defined(COMPILER_MSVC) || defined(COMPILER_MINGW)
+ // If you need '__declspec' compatibility, add extra compilers to the above as necessary
+ #define LIBARDOUR_IS_IN_WINDLL 1
+ #else
+ #define LIBARDOUR_IS_IN_WINDLL 0
+ #endif
+#endif
+
+#if LIBARDOUR_IS_IN_WINDLL && !defined(LIBARDOUR_API)
+ #if defined(BUILDING_LIBARDOUR)
+ #define LIBARDOUR_API __declspec(dllexport)
+ #define LIBARDOUR_APICALLTYPE __cdecl
+ #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point
+ #define LIBARDOUR_API __declspec(dllimport)
+ #define LIBARDOUR_APICALLTYPE __cdecl
+ #else
+ #error "Attempting to define __declspec with an incompatible compiler !"
+ #endif
+#elif !defined(LIBARDOUR_API)
+ // Other compilers / platforms could be accommodated here (as an example, see LIBARDOUR_HELPER_DLL, below)
+ #define LIBARDOUR_API
+ #define LIBARDOUR_APICALLTYPE
+#endif
+
+
/* _WIN32 is defined by most compilers targetting Windows, but within the
* ardour source tree, we also define COMPILER_MSVC or COMPILER_MINGW depending
* on how a Windows build is built.
*/
#include <iostream>
+#include <vector>
+
+#include <glibmm/timer.h>
#include "pbd/error.h"
#include "pbd/stacktrace.h"
using namespace PBD;
namespace Evoral {
- template class EventRingBuffer<timestamp_t>;
+ template class EventRingBuffer<MIDI::timestamp_t>;
}
pthread_t AsyncMIDIPort::_process_thread;
, _last_write_timestamp (0)
, output_fifo (512)
, input_fifo (1024)
+#ifndef PLATFORM_WINDOWS
, xthread (true)
+#endif
{
}
}
void
-AsyncMIDIPort::flush_output_fifo (pframes_t nframes)
+AsyncMIDIPort::flush_output_fifo (MIDI::pframes_t nframes)
{
RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0 } };
size_t written;
}
void
-AsyncMIDIPort::cycle_start (pframes_t nframes)
+AsyncMIDIPort::cycle_start (MIDI::pframes_t nframes)
{
_currently_in_cycle = true;
MidiPort::cycle_start (nframes);
for (MidiBuffer::iterator b = mb.begin(); b != mb.end(); ++b) {
input_fifo.write (when, (Evoral::EventType) 0, (*b).size(), (*b).buffer());
}
-
+
+#ifndef PLATFORM_WINDOWS
if (!mb.empty()) {
xthread.wakeup ();
}
+#endif
}
-
}
void
-AsyncMIDIPort::cycle_end (pframes_t nframes)
+AsyncMIDIPort::cycle_end (MIDI::pframes_t nframes)
{
if (ARDOUR::Port::sends_output()) {
/* move any additional data from output FIFO into the port
if (vec.len[0] + vec.len[1] >= output_fifo.bufsize() - 1) {
break;
}
- usleep (check_interval_usecs);
+ Glib::usleep (check_interval_usecs);
}
}
int
-AsyncMIDIPort::write (const byte * msg, size_t msglen, timestamp_t timestamp)
+AsyncMIDIPort::write (const MIDI::byte * msg, size_t msglen, MIDI::timestamp_t timestamp)
{
int ret = 0;
}
if (timestamp >= _cycle_nframes) {
- std::cerr << "attempting to write MIDI event of " << msglen << " bytes at time "
+ std::cerr << "attempting to write MIDI event of " << msglen << " MIDI::bytes at time "
<< timestamp << " of " << _cycle_nframes
<< " (this will not work - needs a code fix)"
<< std::endl;
timestamp_t time;
Evoral::EventType type;
uint32_t size;
- byte buffer[input_fifo.capacity()];
+ vector<MIDI::byte> buffer(input_fifo.capacity());
- while (input_fifo.read (&time, &type, &size, buffer)) {
+ while (input_fifo.read (&time, &type, &size, &buffer[0])) {
_parser->set_timestamp (time);
for (uint32_t i = 0; i < size; ++i) {
_parser->scanner (buffer[i]);
}
void
-AsyncMIDIPort::parse (framecnt_t)
+AsyncMIDIPort::parse (MIDI::framecnt_t)
{
MIDI::byte buf[1];
#include <fcntl.h>
#include <cstdlib>
#include <ctime>
-#include <sys/stat.h>
-#include <sys/mman.h>
#include "pbd/error.h"
#include "pbd/xml++.h"
boost::shared_ptr<ChannelList> c = channels.reader();
for (chan = c->begin(); chan != c->end(); ++chan) {
- (*chan)->playback_buf->increment_read_ptr (std::llabs(distance));
+ (*chan)->playback_buf->increment_read_ptr (llabs(distance));
}
if (first_recordable_frame < max_framepos) {
*/
+#ifdef WAF_BUILD
+#include "libardour-config.h"
+#endif
+
#include <sstream>
#include <libxml/uri.h>
+#ifdef HAVE_LRDF
#include <lrdf.h>
+#endif
+
#include <glibmm/miscutils.h>
#include <glibmm/convert.h>
touch_file(sfdb_file_path);
+#ifdef HAVE_LRDF
lrdf_read_file(src.c_str());
+#endif
}
AudioLibrary::~AudioLibrary ()
void
AudioLibrary::save_changes ()
{
+#ifdef HAVE_LRDF
if (lrdf_export_by_source(src.c_str(), src.substr(5).c_str())) {
PBD::warning << string_compose(_("Could not open %1. Audio Library not saved"), src) << endmsg;
}
+#endif
}
void
AudioLibrary::set_tags (string member, vector<string> tags)
{
+#ifdef HAVE_LRDF
sort (tags.begin(), tags.end());
tags.erase (unique(tags.begin(), tags.end()), tags.end());
for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) {
lrdf_add_triple (src.c_str(), file_uri.c_str(), TAG, (*i).c_str(), lrdf_literal);
}
+#endif
}
vector<string>
AudioLibrary::get_tags (string member)
{
vector<string> tags;
+#ifdef HAVE_LRDF
lrdf_statement pattern;
pattern.subject = strdup(Glib::filename_to_uri(member).c_str());
lrdf_free_statements (matches);
sort (tags.begin(), tags.end());
-
+#endif
return tags;
}
void
AudioLibrary::search_members_and (vector<string>& members, const vector<string>& tags)
{
+#ifdef HAVE_LRDF
lrdf_statement **head;
lrdf_statement* pattern = 0;
lrdf_statement* old = 0;
pattern = pattern->next;
delete old;
}
+#endif
}
if (!lm.locked()) {
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
- if (can_internal_playback_seek(std::llabs(playback_distance))) {
+ if (can_internal_playback_seek(llabs(playback_distance))) {
/* TODO should declick */
internal_playback_seek(playback_distance);
}
#include <glibmm/threads.h>
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
+#include <glib/gstdio.h>
#include "ardour/ardour.h"
#include "ardour/audioengine.h"
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());
}
}
#include "pbd/stacktrace.h"
#include "pbd/unknown_type.h"
-#include <jack/weakjack.h>
-
#include "midi++/port.h"
#include "midi++/mmc.h"
#include <sndfile.h>
+#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include <glibmm/fileutils.h>
#include <glibmm/threads.h>
{
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());
}
}
int
AudioFileSource::move_dependents_to_trash()
{
- return ::unlink (peakpath.c_str());
+ return ::g_unlink (peakpath.c_str());
}
void
*/
-#include <sys/stat.h>
+#ifdef COMPILER_MSVC
+#include <sys/utime.h>
+#else
#include <unistd.h>
+#include <utime.h>
+#endif
+#include <sys/stat.h>
#include <fcntl.h>
-#include <poll.h>
#include <float.h>
-#include <utime.h>
#include <cerrno>
#include <ctime>
#include <cmath>
#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>
#include "i18n.h"
+#include "ardour/debug.h"
+
using namespace std;
using namespace ARDOUR;
using namespace PBD;
void
AudioSource::touch_peakfile ()
{
- struct stat statbuf;
+ GStatBuf 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;
}
tbuf.actime = statbuf.st_atime;
tbuf.modtime = time ((time_t*) 0);
- utime (peakpath.c_str(), &tbuf);
+ g_utime (peakpath.c_str(), &tbuf);
}
int
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;
}
int
AudioSource::initialize_peakfile (string audio_path)
{
- struct stat statbuf;
+ GStatBuf statbuf;
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 */
return -1;
}
- /* peakfile does not exist */
+ DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 does not exist\n", peakpath));
_peaks_built = false;
/* 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.
/* 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;
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 */
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;
}
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
+ DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n");
- nread = ::pread (peakfile_fd, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
-
- 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;
+ 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;
}
memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
}
- delete peakfile_descriptor;
return 0;
}
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,
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 */
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;
}
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));
- if ((nread = ::pread (peakfile_fd, staging, sizeof (PeakData) * to_read, start_byte))
- != sizeof (PeakData) * to_read) {
- off_t fend = lseek (peakfile_fd, 0, SEEK_END);
+ off_t offset = lseek (peakfile_fd, start_byte, SEEK_SET);
- 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;
+ 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);
+
+ 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;
+ }
i = 0;
stored_peaks_read = nread / sizeof(PeakData);
}
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)
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);
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;
}
}
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;
{
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;
}
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;
}
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 ();
off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
- 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;
}
_peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
/* 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 */
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;
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 */
}
}
}
- 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;
}
- _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);
}
}
- ret = 0;
-
- out:
- delete [] peakbuf;
- delete [] buf2;
-
- return ret;
+ return 0;
}
void
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;
#include <iostream>
+#include <glibmm/timer.h>
+
#include "pbd/compose.h"
#include "ardour/automation_control.h"
AutomationWatch::thread ()
{
while (_run_thread) {
- usleep ((useconds_t) floor (Config->get_automation_interval_msecs() * 1000));
+ Glib::usleep ((gulong) floor (Config->get_automation_interval_msecs() * 1000));
timer ();
}
}
namespace ARDOUR {
-SearchPath
+Searchpath
backend_search_path ()
{
- SearchPath spath(user_config_directory ());
+ Searchpath spath(user_config_directory ());
spath += ardour_dll_directory ();
spath.add_subdirectory_to_paths(backend_dir_name);
- spath += SearchPath(Glib::getenv(backend_env_variable_name));
+ spath += Searchpath(Glib::getenv(backend_env_variable_name));
return spath;
}
#include <iostream>
#include <sstream>
#include <iomanip>
+#include <vector>
#include <glibmm.h>
static void
snprintf_bounded_null_filled (char* target, size_t target_size, char const * fmt, ...)
{
- char buf[target_size+1];
+ std::vector<char> buf(target_size+1);
va_list ap;
va_start (ap, fmt);
- vsnprintf (buf, target_size+1, fmt, ap);
+ vsnprintf (&buf[0], target_size+1, fmt, ap);
va_end (ap);
memset (target, 0, target_size);
- memcpy (target, buf, target_size);
+ memcpy (target, &buf[0], target_size);
}
/* random code is 9 digits */
- int random_code = random() % 999999999;
+ int random_code = g_random_int() % 999999999;
/* Serial number is 12 chars */
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
+
+#ifndef PLATFORM_WINDOWS
#include <poll.h>
+#endif
+
#include "pbd/error.h"
#include "pbd/pthread_utils.h"
#include "ardour/butler.h"
Butler::Butler(Session& s)
: SessionHandleRef (s)
- , thread(0)
+ , thread()
, audio_dstream_capture_buffer_size(0)
, audio_dstream_playback_buffer_size(0)
, midi_dstream_buffer_size(0)
}
}
+#ifndef PLATFORM_WINDOWS
int
-Butler::start_thread()
+Butler::setup_request_pipe ()
{
- const float rate = (float)_session.frame_rate();
-
- /* size is in Samples, not bytes */
- audio_dstream_capture_buffer_size = (uint32_t) floor (Config->get_audio_capture_buffer_seconds() * rate);
- audio_dstream_playback_buffer_size = (uint32_t) floor (Config->get_audio_playback_buffer_seconds() * rate);
-
- /* size is in bytes
- * XXX: Jack needs to tell us the MIDI buffer size
- * (i.e. how many MIDI bytes we might see in a cycle)
- */
- midi_dstream_buffer_size = (uint32_t) floor (Config->get_midi_track_buffer_seconds() * rate);
-
- MidiDiskstream::set_readahead_frames ((framecnt_t) (Config->get_midi_readahead() * rate));
-
- should_run = false;
-
if (pipe (request_pipe)) {
error << string_compose(_("Cannot create transport request signal pipe (%1)"),
strerror (errno)) << endmsg;
strerror (errno)) << endmsg;
return -1;
}
+ return 0;
+}
+#endif
+
+int
+Butler::start_thread()
+{
+ const float rate = (float)_session.frame_rate();
+
+ /* size is in Samples, not bytes */
+ audio_dstream_capture_buffer_size = (uint32_t) floor (Config->get_audio_capture_buffer_seconds() * rate);
+ audio_dstream_playback_buffer_size = (uint32_t) floor (Config->get_audio_playback_buffer_seconds() * rate);
+
+ /* size is in bytes
+ * XXX: Jack needs to tell us the MIDI buffer size
+ * (i.e. how many MIDI bytes we might see in a cycle)
+ */
+ midi_dstream_buffer_size = (uint32_t) floor (Config->get_midi_track_buffer_seconds() * rate);
+
+ MidiDiskstream::set_readahead_frames ((framecnt_t) (Config->get_midi_readahead() * rate));
+
+ should_run = false;
+
+#ifndef PLATFORM_WINDOWS
+ if (setup_request_pipe() != 0) return -1;
+#endif
if (pthread_create_and_store ("disk butler", &thread, _thread_work, this)) {
error << _("Session: could not create butler thread") << endmsg;
void
Butler::terminate_thread ()
{
- if (thread) {
- void* status;
- const char c = Request::Quit;
- (void) ::write (request_pipe[1], &c, 1);
- pthread_join (thread, &status);
- }
+ void* status;
+ queue_request (Request::Quit);
+ pthread_join (thread, &status);
}
void *
return ((Butler *) arg)->thread_work ();
}
-void *
-Butler::thread_work ()
+bool
+Butler::wait_for_requests ()
{
- uint32_t err = 0;
-
+#ifndef PLATFORM_WINDOWS
struct pollfd pfd[1];
- bool disk_work_outstanding = false;
- RouteList::iterator i;
- while (true) {
- pfd[0].fd = request_pipe[0];
- pfd[0].events = POLLIN|POLLERR|POLLHUP;
+ pfd[0].fd = request_pipe[0];
+ pfd[0].events = POLLIN|POLLERR|POLLHUP;
- if (poll (pfd, 1, (disk_work_outstanding ? 0 : -1)) < 0) {
+ while(true) {
+ if (poll (pfd, 1, -1) < 0) {
if (errno == EINTR) {
continue;
}
error << string_compose (_("poll on butler request pipe failed (%1)"),
- strerror (errno))
- << endmsg;
+ strerror (errno))
+ << endmsg;
break;
}
}
if (pfd[0].revents & POLLIN) {
+ return true;
+ }
+ }
+ return false;
+#else
+ m_request_sem.wait ();
+ return true;
+#endif
+}
- char req;
+bool
+Butler::dequeue_request (Request::Type& r)
+{
+#ifndef PLATFORM_WINDOWS
+ char req;
+ size_t nread = ::read (request_pipe[0], &req, sizeof (req));
+ if (nread == 1) {
+ r = (Request::Type) req;
+ return true;
+ } else if (nread == 0) {
+ return false;
+ } else if (errno == EAGAIN) {
+ return false;
+ } else {
+ fatal << _("Error reading from butler request pipe") << endmsg;
+ /*NOTREACHED*/
+ }
+#else
+ r = (Request::Type) m_request_state.get();
+#endif
+ return false;
+}
- /* empty the pipe of all current requests */
+ void *
+Butler::thread_work ()
+{
+ uint32_t err = 0;
- while (1) {
- size_t nread = ::read (request_pipe[0], &req, sizeof (req));
- if (nread == 1) {
+ bool disk_work_outstanding = false;
+ RouteList::iterator i;
- switch ((Request::Type) req) {
+ while (true) {
+ if(!disk_work_outstanding) {
+ if (wait_for_requests ()) {
+ Request::Type req;
+
+ /* empty the pipe of all current requests */
+#ifdef PLATFORM_WINDOWS
+ dequeue_request (req);
+ {
+#else
+ while(dequeue_request(req)) {
+#endif
+ switch (req) {
case Request::Run:
should_run = true;
default:
break;
}
-
- } else if (nread == 0) {
- break;
- } else if (errno == EAGAIN) {
- break;
- } else {
- fatal << _("Error reading from butler request pipe") << endmsg;
- /*NOTREACHED*/
}
}
}
}
void
-Butler::summon ()
+Butler::queue_request (Request::Type r)
{
- char c = Request::Run;
+#ifndef PLATFORM_WINDOWS
+ char c = r;
(void) ::write (request_pipe[1], &c, 1);
+#else
+ m_request_state.set (r);
+ m_request_sem.post ();
+#endif
+}
+
+void
+Butler::summon ()
+{
+ queue_request (Request::Run);
}
void
Butler::stop ()
{
Glib::Threads::Mutex::Lock lm (request_lock);
- char c = Request::Pause;
- (void) ::write (request_pipe[1], &c, 1);
+ queue_request (Request::Pause);
paused.wait(request_lock);
}
Butler::wait_until_finished ()
{
Glib::Threads::Mutex::Lock lm (request_lock);
- char c = Request::Pause;
- (void) ::write (request_pipe[1], &c, 1);
+ queue_request (Request::Pause);
paused.wait(request_lock);
}
*/
-#include <dlfcn.h>
+#include <glibmm/module.h>
#include <glibmm/fileutils.h>
#include "ardour/debug.h"
#include "ardour/control_protocol_manager.h"
+
#include "ardour/control_protocol_search_path.h"
+
using namespace ARDOUR;
using namespace std;
using namespace PBD;
cpi.protocol = 0;
delete cpi.state;
cpi.state = 0;
- dlclose (cpi.descriptor->module);
+ delete (Glib::Module*)cpi.descriptor->module;
ProtocolStatusChange (&cpi);
string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name));
}
- dlclose (descriptor->module);
+ delete (Glib::Module*)descriptor->module;
}
return 0;
ControlProtocolDescriptor*
ControlProtocolManager::get_descriptor (string path)
{
- void *module;
+ Glib::Module* module = new Glib::Module(path);
ControlProtocolDescriptor *descriptor = 0;
ControlProtocolDescriptor* (*dfunc)(void);
- const char *errstr;
+ void* func = 0;
- if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
- error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
+ if (!(*module)) {
+ error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, Glib::Module::get_last_error()) << endmsg;
+ delete module;
return 0;
}
-
- dfunc = (ControlProtocolDescriptor* (*)(void)) dlsym (module, "protocol_descriptor");
-
- if ((errstr = dlerror()) != 0) {
+ if (!module->get_symbol("protocol_descriptor", func)) {
error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg;
- error << errstr << endmsg;
- dlclose (module);
+ error << Glib::Module::get_last_error() << endmsg;
+ delete module;
return 0;
}
+ dfunc = (ControlProtocolDescriptor* (*)(void))func;
descriptor = dfunc();
+
if (descriptor) {
- descriptor->module = module;
+ descriptor->module = (void*)module;
} else {
- dlclose (module);
+ delete module;
}
return descriptor;
namespace ARDOUR {
-SearchPath
+Searchpath
control_protocol_search_path ()
{
- SearchPath spath(user_config_directory ());
+ Searchpath spath(user_config_directory ());
spath += ardour_dll_directory ();
spath.add_subdirectory_to_paths (surfaces_dir_name);
- spath += SearchPath(Glib::getenv(surfaces_env_variable_name));
+ spath += Searchpath(Glib::getenv(surfaces_env_variable_name));
return spath;
}
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");
#include "ardour/session.h"
#include "ardour/types.h"
+#ifdef COMPILER_MSVC
+#pragma warning(disable:4305)
+#endif
+
using namespace ARDOUR;
const Sample Session::default_click_emphasis[] = {
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");
const char* const backend_dir_name = X_("backends");
#include <cstdlib>
#include <ctime>
#include <sys/stat.h>
-#include <sys/mman.h>
#include <glibmm/threads.h>
set<Evoral::Parameter> const a = processor->what_can_be_automated ();
- for (set<Evoral::Parameter>::iterator i = a.begin (); i != a.end (); ++i) {
+ for (set<Evoral::Parameter>::const_iterator i = a.begin (); i != a.end (); ++i) {
boost::shared_ptr<AutomationList> al = processor->automation_control(*i)->alist();
XMLNode & before = al->get_state ();
bool const things_moved = al->move_ranges (movements);
*/
rolling = _session.transport_speed() != 0.0f;
- possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
+ possibly_recording = (rolling << 2) | ((int)record_enabled() << 1) | (int)can_record;
change = possibly_recording ^ last_possibly_recording;
if (possibly_recording == last_possibly_recording) {
SampleRate best_match = SR_None;
#define DO_SR_COMPARISON(rate) \
- diff = std::fabs((rate) - sample_rate); \
+ diff = std::fabs((double)((rate) - sample_rate)); \
if(diff < smallest_diff) { \
smallest_diff = diff; \
best_match = (rate); \
namespace ARDOUR {
-SearchPath
+Searchpath
export_formats_search_path ()
{
- SearchPath spath (ardour_data_search_path());
+ Searchpath spath (ardour_data_search_path());
spath.add_subdirectory_to_paths (export_formats_dir_name);
bool export_formats_path_defined = false;
- SearchPath spath_env (Glib::getenv(export_env_variable_name, export_formats_path_defined));
+ Searchpath spath_env (Glib::getenv(export_env_variable_name, export_formats_path_defined));
if (export_formats_path_defined) {
spath += spath_env;
#include "ardour/export_graph_builder.h"
+#include <vector>
+
#include <glibmm/miscutils.h>
#include "audiographer/process_context.h"
{
std::string tmpfile_path = parent.session.session_directory().export_path();
tmpfile_path = Glib::build_filename(tmpfile_path, "XXXXXX");
- char tmpfile_path_buf[tmpfile_path.size() + 1];
- std::copy(tmpfile_path.begin(), tmpfile_path.end(), tmpfile_path_buf);
+ std::vector<char> tmpfile_path_buf(tmpfile_path.size() + 1);
+ std::copy(tmpfile_path.begin(), tmpfile_path.end(), tmpfile_path_buf.begin());
tmpfile_path_buf[tmpfile_path.size()] = '\0';
config = new_config;
normalizer->add_output (threader);
int format = ExportFormatBase::F_RAW | ExportFormatBase::SF_Float;
- tmp_file.reset (new TmpFile<float> (tmpfile_path_buf, format, channels, config.format->sample_rate()));
+ tmp_file.reset (new TmpFile<float> (&tmpfile_path_buf[0], format, channels, config.format->sample_rate()));
tmp_file->FileWritten.connect_same_thread (post_processing_connection,
boost::bind (&Normalizer::start_post_processing, this));
#include "ardour/export_handler.h"
+#include <glib/gstdio.h>
#include <glibmm.h>
#include <glibmm/convert.h>
} 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());
}
}
ExportProfileManager::deserialize_format (XMLNode & root)
{
XMLProperty * prop;
- UUID id;
+ PBD::UUID id;
if ((prop = root.property ("id"))) {
id = prop->value();
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)
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) {
/* 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;
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;
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;
/* 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) {
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;
goto out;
}
+#ifndef PLATFORM_WINDOWS
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;
std::string
ardour_dll_directory ()
{
+#ifdef PLATFORM_WINDOWS
+ 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 PLATFORM_WINDOWS
+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
+Searchpath
ardour_config_search_path ()
{
- static SearchPath search_path;
+ static Searchpath search_path;
if (search_path.empty()) {
search_path += user_config_directory();
-
+#ifdef PLATFORM_WINDOWS
+ 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");
::exit (1);
}
- search_path += SearchPath (s);
+ search_path += Searchpath (s);
+#endif
}
return search_path;
}
-SearchPath
+Searchpath
ardour_data_search_path ()
{
- static SearchPath search_path;
+ static Searchpath search_path;
if (search_path.empty()) {
search_path += user_config_directory();
-
+#ifdef PLATFORM_WINDOWS
+ 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");
::exit (1);
}
- search_path += SearchPath (s);
+ search_path += Searchpath (s);
+#endif
}
return search_path;
#include <glibmm/miscutils.h>
#include "pbd/compose.h"
+#include "pbd/pathexpand.h"
#include "pbd/error.h"
#include "ardour/filename_extensions.h"
find_session (string str, string& path, string& snapshot, bool& isnew)
{
struct stat statbuf;
- char buf[PATH_MAX+1];
isnew = false;
- if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
- error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
- return -1;
- }
-
- str = buf;
+ str = canonical_path (str);
/* check to see if it exists, and what it is */
#include "libardour-config.h"
#endif
+#ifdef interface
+#undef interface
+#endif
+
#include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
#include <cstdlib>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
+#ifndef PLATFORM_WINDOWS
#include <sys/resource.h>
+#endif
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "ardour/audio_unit.h"
#endif
-#ifdef __SSE__
+#if defined(__SSE__) || defined(USE_XMMINTRIN)
#include <xmmintrin.h>
#endif
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
+#ifdef HAVE_LRDF
#include <lrdf.h>
+#endif
#include "pbd/cpus.h"
#include "pbd/error.h"
static void
lotsa_files_please ()
{
+#ifndef PLATFORM_WINDOWS
struct rlimit rl;
if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
} else {
error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
}
+#endif
}
bool
// allow ardour the absolute maximum number of open files
lotsa_files_please ();
+#ifdef HAVE_LRDF
lrdf_init();
+#endif
Library = new AudioLibrary;
BootMessage (_("Loading configuration"));
ARDOUR::AudioEngine::destroy ();
delete Library;
+#ifdef HAVE_LRDF
lrdf_cleanup ();
+#endif
delete &ControlProtocolManager::instance();
#ifdef WINDOWS_VST_SUPPORT
fst_exit ();
ARDOUR::find_bindings_files (map<string,string>& files)
{
vector<std::string> found;
- SearchPath spath = ardour_config_search_path();
+ Searchpath spath = ardour_config_search_path();
if (getenv ("ARDOUR_SAE")) {
Glib::PatternSpec pattern("*SAE-*.bindings");
microseconds_t
ARDOUR::get_microseconds ()
{
+#ifdef PLATFORM_WINDOWS
+ microseconds_t ret = 0;
+ LARGE_INTEGER freq, time;
+
+ if (QueryPerformanceFrequency(&freq))
+ if (QueryPerformanceCounter(&time))
+ ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
+
+ return ret;
+#else
struct timespec ts;
if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
/* EEEK! */
return 0;
}
return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
+#endif
}
#include "pbd/compose.h"
#include "pbd/debug_rt_alloc.h"
+#include "pbd/pthread_utils.h"
#include "ardour/debug.h"
#include "ardour/graph.h"
/* update the number of threads that will still be sleeping */
_execution_tokens -= wakeup;
- DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 signals %2\n", pthread_self(), wakeup));
+ DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 signals %2\n", pthread_name(), wakeup));
for (int i = 0; i < wakeup; i++) {
_execution_sem.signal ();
while (to_run == 0) {
_execution_tokens += 1;
pthread_mutex_unlock (&_trigger_mutex);
- DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 goes to sleep\n", pthread_self()));
+ DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 goes to sleep\n", pthread_name()));
_execution_sem.wait ();
if (_quit_threads) {
return true;
}
- DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 is awake\n", pthread_self()));
+ DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 is awake\n", pthread_name()));
pthread_mutex_lock (&_trigger_mutex);
if (_trigger_queue.size()) {
to_run = _trigger_queue.back();
to_run->process();
to_run->finish (_current_chain);
- DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 has finished run_one()\n", pthread_self()));
+ DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 has finished run_one()\n", pthread_name()));
return false;
}
assert (route);
- DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 runs route %2\n", pthread_self(), route->name()));
+ DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 runs route %2\n", pthread_name(), route->name()));
if (_process_silent) {
retval = route->silent_roll (_process_nframes, _process_start_frame, _process_end_frame, need_butler);
#include <sndfile.h>
#include <samplerate.h>
+#include <glib/gstdio.h>
#include <glibmm.h>
#include <boost/scoped_array.hpp>
}
static std::string
-get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint channel, uint channels)
+get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint32_t channel, uint32_t channels)
{
char buf[PATH_MAX+1];
bool goodfile = false;
}
static vector<string>
-get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels)
+get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint32_t channels)
{
vector<string> new_paths;
const string basename = basename_nosuffix (import_file_path);
SessionDirectory sdir(session_dir);
- for (uint n = 0; n < channels; ++n) {
+ for (uint32_t n = 0; n < channels; ++n) {
const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
static bool
map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
- uint /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
+ uint32_t /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
{
for (vector<string>::const_iterator i = new_paths.begin();
i != new_paths.end(); ++i)
static bool
create_mono_sources_for_writing (const vector<string>& new_paths,
- Session& sess, uint samplerate,
+ Session& sess, uint32_t samplerate,
vector<boost::shared_ptr<Source> >& newfiles,
framepos_t timeline_position)
{
static string
compose_status_message (const string& path,
- uint file_samplerate,
- uint session_samplerate,
- uint /* current_file */,
- uint /* total_files */)
+ uint32_t file_samplerate,
+ uint32_t session_samplerate,
+ uint32_t /* current_file */,
+ uint32_t /* total_files */)
{
if (file_samplerate != session_samplerate) {
return string_compose (_("Resampling %1 from %2kHz to %3kHz"),
{
const framecnt_t nframes = ResampledImportableSource::blocksize;
boost::shared_ptr<AudioFileSource> afs;
- uint channels = source->channels();
+ uint32_t channels = source->channels();
boost::scoped_array<float> data(new float[nframes * channels]);
vector<boost::shared_array<Sample> > channel_data;
- for (uint n = 0; n < channels; ++n) {
+ for (uint32_t n = 0; n < channels; ++n) {
channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
}
*/
float peak = 0;
- uint read_count = 0;
+ uint32_t read_count = 0;
while (!status.cancel) {
framecnt_t const nread = source->read (data.get(), nframes);
progress_base = 0.5;
}
- uint read_count = 0;
+ uint32_t read_count = 0;
while (!status.cancel) {
framecnt_t nread, nfread;
- uint x;
- uint chn;
+ uint32_t x;
+ uint32_t chn;
if ((nread = source->read (data.get(), nframes)) == 0) {
+#ifdef PLATFORM_WINDOWS
+ /* Flush the data once we've finished importing the file. Windows can */
+ /* cache the data for very long periods of time (perhaps not writing */
+ /* it to disk until Ardour closes). So let's force it to flush now. */
+ for (chn = 0; chn < channels; ++chn)
+ if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0)
+ afs->flush ();
+#endif
break;
}
boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
if (fs) {
- ::unlink (fs->path().c_str());
+ ::g_unlink (fs->path().c_str());
}
}
Sources all_new_sources;
boost::shared_ptr<AudioFileSource> afs;
boost::shared_ptr<SMFSource> smfs;
- uint channels = 0;
+ uint32_t channels = 0;
status.sources.clear ();
#include <fstream>
#include <algorithm>
#include <cmath>
+#include <vector>
#include <unistd.h>
#include <locale.h>
int
IO::ensure_ports_locked (ChanCount count, bool clear, bool& changed)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
boost::shared_ptr<Port> port;
int
IO::ensure_ports (ChanCount count, bool clear, void* src)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
bool changed = false;
int
IO::ensure_io (ChanCount count, bool clear, void* src)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
return ensure_ports (count, clear, src);
}
limit = name_size - AudioEngine::instance()->my_name().length() - (suffix.length() + 5);
- char buf1[name_size+1];
- char buf2[name_size+1];
+ std::vector<char> buf1(name_size+1);
+ std::vector<char> buf2(name_size+1);
/* colons are illegal in port names, so fix that */
string nom = _name.val();
replace_all (nom, ":", ";");
- snprintf (buf1, name_size+1, ("%.*s/%s"), limit, nom.c_str(), suffix.c_str());
+ snprintf (&buf1[0], name_size+1, ("%.*s/%s"), limit, nom.c_str(), suffix.c_str());
- int port_number = find_port_hole (buf1);
- snprintf (buf2, name_size+1, "%s %d", buf1, port_number);
+ int port_number = find_port_hole (&buf1[0]);
+ snprintf (&buf2[0], name_size+1, "%s %d", &buf1[0], port_number);
- return string (buf2);
+ return string (&buf2[0]);
}
int32_t
*/
for (n = 1; n < 9999; ++n) {
- size_t size = AudioEngine::instance()->port_name_size() + 1;
- char buf[size];
+ std::vector<char> buf (AudioEngine::instance()->port_name_size());
PortSet::iterator i = _ports.begin();
- snprintf (buf, size, _("%s %u"), base, n);
+ snprintf (&buf[0], jack_port_name_size(), _("%s %u"), base, n);
for ( ; i != _ports.end(); ++i) {
- if (i->name() == buf) {
+ if (string(i->name()) == string(&buf[0])) {
break;
}
}
*/
+#ifdef WAF_BUILD
+#include "libardour-config.h"
+#endif
+
#include <inttypes.h>
#include <vector>
#include <cstdlib>
#include <cstdio> // so libraptor doesn't complain
#include <cmath>
+#ifndef COMPILER_MSVC
#include <dirent.h>
+#endif
#include <sys/stat.h>
#include <cerrno>
+#ifdef HAVE_LRDF
#include <lrdf.h>
+#endif
#include "pbd/compose.h"
#include "pbd/error.h"
using namespace ARDOUR;
using namespace PBD;
-LadspaPlugin::LadspaPlugin (void *mod, AudioEngine& e, Session& session, uint32_t index, framecnt_t rate)
+LadspaPlugin::LadspaPlugin (string module_path, AudioEngine& e, Session& session, uint32_t index, framecnt_t rate)
: Plugin (e, session)
{
- init (mod, index, rate);
+ init (module_path, index, rate);
}
LadspaPlugin::LadspaPlugin (const LadspaPlugin &other)
: Plugin (other)
{
- init (other._module, other._index, other._sample_rate);
+ init (other._module_path, other._index, other._sample_rate);
for (uint32_t i = 0; i < parameter_count(); ++i) {
_control_data[i] = other._shadow_data[i];
}
void
-LadspaPlugin::init (void *mod, uint32_t index, framecnt_t rate)
+LadspaPlugin::init (string module_path, uint32_t index, framecnt_t rate)
{
+ void* func;
LADSPA_Descriptor_Function dfunc;
uint32_t i, port_cnt;
- const char *errstr;
- _module = mod;
+ _module_path = module_path;
+ _module = new Glib::Module(_module_path);
_control_data = 0;
_shadow_data = 0;
_latency_control_port = 0;
_was_activated = false;
- dfunc = (LADSPA_Descriptor_Function) dlsym (_module, "ladspa_descriptor");
+ if (!(*_module)) {
+ error << _("LADSPA: Unable to open module: ") << Glib::Module::get_last_error() << endmsg;
+ delete _module;
+ throw failed_constructor();
+ }
- if ((errstr = dlerror()) != NULL) {
+ if (!_module->get_symbol("ladspa_descriptor", func)) {
error << _("LADSPA: module has no descriptor function.") << endmsg;
throw failed_constructor();
}
+ dfunc = (LADSPA_Descriptor_Function)func;
+
if ((_descriptor = dfunc (index)) == 0) {
error << _("LADSPA: plugin has gone away since discovery!") << endmsg;
throw failed_constructor();
deactivate ();
cleanup ();
- /* XXX who should close a plugin? */
-
- // dlclose (module);
+ // glib has internal reference counting on modules so this is ok
+ delete _module;
delete [] _control_data;
delete [] _shadow_data;
boost::shared_ptr<Plugin::ScalePoints>
LadspaPlugin::get_scale_points(uint32_t port_index) const
{
+ boost::shared_ptr<Plugin::ScalePoints> ret;
+#ifdef HAVE_LRDF
const uint32_t id = atol(unique_id().c_str());
lrdf_defaults* points = lrdf_get_scale_values(id, port_index);
- boost::shared_ptr<Plugin::ScalePoints> ret;
if (!points) {
return ret;
}
}
lrdf_free_setting_values(points);
+#endif
return ret;
}
LadspaPluginInfo::load (Session& session)
{
try {
- PluginPtr plugin;
- void *module;
-
- if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
- error << string_compose(_("LADSPA: cannot load module from \"%1\""), path) << endmsg;
- error << dlerror() << endmsg;
- return PluginPtr ((Plugin*) 0);
- } else {
- plugin.reset (new LadspaPlugin (module, session.engine(), session, index, session.frame_rate()));
- }
-
+ PluginPtr plugin (new LadspaPlugin (path, session.engine(), session, index, session.frame_rate()));
plugin->set_info(PluginInfoPtr(new LadspaPluginInfo(*this)));
return plugin;
}
void
LadspaPlugin::find_presets ()
{
+#ifdef HAVE_LRDF
uint32_t id;
std::string unique (unique_id());
}
lrdf_free_uris(set_uris);
}
+#endif
}
bool
LadspaPlugin::load_preset (PresetRecord r)
{
+#ifdef HAVE_LRDF
lrdf_defaults* defs = lrdf_get_setting_values (r.uri.c_str());
if (defs) {
}
Plugin::load_preset (r);
+#endif
return true;
}
static void
lrdf_remove_preset (const char* /*source*/, const char *setting_uri)
{
+#ifdef HAVE_LRDF
lrdf_statement p;
lrdf_statement *q;
lrdf_statement *i;
p.predicate = NULL;
p.object = NULL;
lrdf_remove_matches (&p);
+#endif
}
void
LadspaPlugin::do_remove_preset (string name)
{
+#ifdef HAVE_LRDF
string const envvar = preset_envvar ();
if (envvar.empty()) {
warning << _("Could not locate HOME. Preset not removed.") << endmsg;
lrdf_remove_preset (source.c_str(), p->uri.c_str ());
write_preset_file (envvar);
+#endif
}
string
bool
LadspaPlugin::write_preset_file (string envvar)
{
+#ifdef HAVE_LRDF
string path = string_compose("%1/.ladspa", envvar);
if (g_mkdir_with_parents (path.c_str(), 0775)) {
warning << string_compose(_("Could not create %1. Preset not saved. (%2)"), path, strerror(errno)) << endmsg;
}
return true;
+#else
+ return false;
+#endif
}
string
LadspaPlugin::do_save_preset (string name)
{
+#ifdef HAVE_LRDF
/* make a vector of pids that are input parameters */
vector<int> input_parameter_pids;
for (uint32_t i = 0; i < parameter_count(); ++i) {
lrdf_defaults defaults;
defaults.count = input_parameter_pids.size ();
- lrdf_portvalue portvalues[input_parameter_pids.size()];
- defaults.items = portvalues;
+ std::vector<lrdf_portvalue> portvalues(input_parameter_pids.size());
+ defaults.items = &portvalues[0];
for (vector<int>::size_type i = 0; i < input_parameter_pids.size(); ++i) {
portvalues[i].pid = input_parameter_pids[i];
}
return uri;
+#else
+ return string();
+#endif
}
LADSPA_PortDescriptor
--- /dev/null
+/*
+ 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 PLATFORM_WINDOWS
+ 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 (path_expand ("~/Library/Audio/Plug-Ins/LADSPA"));
+ spath.push_back ("/Library/Audio/Plug-Ins/LADSPA");
+#endif
+
+ return spath_env + spath;
+}
+
+} // namespace ARDOUR
*/
#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"
}
void
-LTC_Slave::parse_ltc(const pframes_t nframes, const Sample* const in, const framecnt_t posinfo)
+LTC_Slave::parse_ltc(const ARDOUR::pframes_t nframes, const Sample* const in, const ARDOUR::framecnt_t posinfo)
{
pframes_t i;
unsigned char sound[8192];
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;
snprintf(delta, sizeof(delta), _("flywheel"));
} else {
snprintf(delta, sizeof(delta), "\u0394<span foreground=\"green\" face=\"monospace\" >%s%s%" PRIi64 "</span>sm",
- LEADINGZERO(abs(current_delta)), PLUSMINUS(-current_delta), abs(current_delta));
+ LEADINGZERO(llabs(current_delta)), PLUSMINUS(-current_delta), llabs(current_delta));
}
return std::string(delta);
}
namespace ARDOUR {
-SearchPath
+Searchpath
lv2_bundled_search_path ()
{
- SearchPath spath( ardour_dll_directory () );
+ Searchpath spath( ardour_dll_directory () );
spath.add_subdirectory_to_paths ("LV2");
return spath;
*subframes = 0;
*type = aev->body.type;
*size = aev->body.size;
- *data = LV2_ATOM_BODY(&aev->body);
+ *data = (uint8_t*)LV2_ATOM_BODY(&aev->body);
break;
}
#include <cstdlib>
#include <cstring>
+#include <glib/gstdio.h>
#include <giomm/file.h>
#include <glib/gprintf.h>
#include <glibmm.h>
name + ".ttl"
)
);
- unlink(preset_file.c_str());
+ ::g_unlink(preset_file.c_str());
}
bool
uint32_t size,
const uint8_t* body)
{
- const uint32_t buf_size = sizeof(UIMessage) + size;
- uint8_t buf[buf_size];
+ const uint32_t buf_size = sizeof(UIMessage) + size;
+ vector<uint8_t> buf(buf_size);
- UIMessage* msg = (UIMessage*)buf;
+ UIMessage* msg = (UIMessage*)&buf[0];
msg->index = index;
msg->protocol = protocol;
msg->size = size;
memcpy(msg + 1, body, size);
- return (dest->write(buf, buf_size) == buf_size);
+ return (dest->write(&buf[0], buf_size) == buf_size);
}
bool
error << "Error reading from Plugin=>UI RingBuffer" << endmsg;
break;
}
- uint8_t body[msg.size];
- if (_to_ui->read(body, msg.size) != msg.size) {
+ vector<uint8_t> body(msg.size);
+ if (_to_ui->read(&body[0], msg.size) != msg.size) {
error << "Error reading from Plugin=>UI RingBuffer" << endmsg;
break;
}
- sink(controller, msg.index, msg.size, msg.protocol, body);
+ sink(controller, msg.index, msg.size, msg.protocol, &body[0]);
read_space -= sizeof(msg) + msg.size;
}
error << "Error reading from UI=>Plugin RingBuffer" << endmsg;
break;
}
- uint8_t body[msg.size];
- if (_from_ui->read(body, msg.size) != msg.size) {
+ vector<uint8_t> body(msg.size);
+ if (_from_ui->read(&body[0], msg.size) != msg.size) {
error << "Error reading from UI=>Plugin RingBuffer" << endmsg;
break;
}
if (msg.protocol == urids.atom_eventTransfer) {
LV2_Evbuf* buf = _ev_buffers[msg.index];
LV2_Evbuf_Iterator i = lv2_evbuf_end(buf);
- const LV2_Atom* const atom = (const LV2_Atom*)body;
+ const LV2_Atom* const atom = (const LV2_Atom*)&body[0];
if (!lv2_evbuf_write(&i, nframes, 0, atom->type, atom->size,
(const uint8_t*)(atom + 1))) {
error << "Failed to write data to LV2 event buffer\n";
vector<string *> *plugin_objects = scanner (ARDOUR::lv2_bundled_search_path().to_string(), lv2_filter, 0, true, true);
if (plugin_objects) {
for ( vector<string *>::iterator x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
-#ifdef WINDOWS
+#ifdef PLATFORM_WINDOWS
string uri = "file:///" + **x + "/";
#else
string uri = "file://" + **x + "/";
#include <algorithm>
#include <cmath>
+#include <limits>
#include "pbd/compose.h"
PeakMeter::reset_max ()
{
for (size_t i = 0; i < _max_peak_power.size(); ++i) {
- _max_peak_power[i] = -INFINITY;
+ _max_peak_power[i] = -std::numeric_limits<float>::infinity();
_max_peak_signal[i] = 0;
}
if (n < n_midi) {
_visible_peak_power[n] = 0;
} else {
- _visible_peak_power[n] = -INFINITY;
+ _visible_peak_power[n] = -std::numeric_limits<float>::infinity();
}
}
}
_peak_signal[n] = 0; /* ... to here */
if (n < n_midi) {
- _max_peak_power[n] = -INFINITY; // std::max (new_peak, _max_peak_power[n]); // XXX
+ _max_peak_power[n] = -std::numeric_limits<float>::infinity(); // std::max (new_peak, _max_peak_power[n]); // XXX
_max_peak_signal[n] = 0;
if (midi_meter_falloff == 0.0f || new_peak > _visible_peak_power[n]) {
;
} else {
// do falloff
new_peak = _visible_peak_power[n] - (audio_meter_falloff);
- _visible_peak_power[n] = std::max (new_peak, -INFINITY);
+ _visible_peak_power[n] = std::max (new_peak, -std::numeric_limits<float>::infinity());
}
}
}
#include <cmath>
#include <errno.h>
-#include <poll.h>
#include <sys/types.h>
#include <unistd.h>
#include "pbd/error.h"
}
void
-MIDIClock_Slave::position (Parser& /*parser*/, byte* message, size_t size)
+MIDIClock_Slave::position (Parser& /*parser*/, MIDI::byte* message, size_t size)
{
// we are note supposed to get position messages while we are running
// so lets be robust and ignore those
}
assert(size == 3);
- byte lsb = message[1];
- byte msb = message[2];
+ MIDI::byte lsb = message[1];
+ MIDI::byte msb = message[2];
assert((lsb <= 0x7f) && (msb <= 0x7f));
uint16_t position_in_sixteenth_notes = (uint16_t(msb) << 7) | uint16_t(lsb);
#include <fcntl.h>
#include <cstdlib>
#include <ctime>
-#include <strings.h> // for ffs(3)
#include <sys/stat.h>
-#include <sys/mman.h>
#include "pbd/error.h"
+#include "pbd/ffs.h"
#include "pbd/basename.h"
#include <glibmm/threads.h>
#include "pbd/xml++.h"
break;
case ForceChannel:
if (ev.is_channel_event()) {
- ev.set_channel (ffs(mask) - 1);
+ ev.set_channel (PBD::ffs(mask) - 1);
}
_capture_buf->write(transport_frame + loop_offset + ev.time(),
ev.type(), ev.size(), ev.buffer());
#include "ardour/session.h"
#include "ardour/session_directory.h"
#include "ardour/midi_patch_manager.h"
+
#include "ardour/midi_patch_search_path.h"
#include "i18n.h"
_master_devices_by_model.clear();
_all_models.clear();
- SearchPath search_path = midi_patch_search_path ();
+ Searchpath search_path = midi_patch_search_path ();
Glib::PatternSpec pattern (string("*.midnam"));
vector<std::string> result;
namespace ARDOUR {
-SearchPath
+Searchpath
midi_patch_search_path ()
{
- SearchPath spath (ardour_data_search_path());
+ Searchpath spath (ardour_data_search_path());
spath.add_subdirectory_to_paths(midi_patch_dir_name);
bool midi_patch_path_defined = false;
- SearchPath spath_env (Glib::getenv(midi_patch_env_variable_name, midi_patch_path_defined));
+ Searchpath spath_env (Glib::getenv(midi_patch_env_variable_name, midi_patch_path_defined));
if (midi_patch_path_defined) {
spath += spath_env;
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
-#include <poll.h>
#include <float.h>
#include <cerrno>
#include <ctime>
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <strings.h> // for ffs(3)
-
+#include "pbd/ffs.h"
#include "pbd/enumwriter.h"
#include "pbd/convert.h"
#include "evoral/midi_util.h"
if (!lm.locked()) {
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
- if (can_internal_playback_seek(std::llabs(playback_distance))) {
+ if (can_internal_playback_seek(llabs(playback_distance))) {
/* TODO should declick, and/or note-off */
internal_playback_seek(playback_distance);
}
}
break;
case ForceChannel:
- ev.set_channel (ffs (mask) - 1);
+ ev.set_channel (PBD::ffs (mask) - 1);
++e;
break;
case AllChannels:
MidiTrack::MidiControl::set_value(double val)
{
bool valid = false;
- if (std::isinf(val)) {
+ if (isinf(val)) {
cerr << "MIDIControl value is infinity" << endl;
- } else if (std::isnan(val)) {
+ } else if (isnan(val)) {
cerr << "MIDIControl value is NaN" << endl;
} else if (val < _list->parameter().min()) {
cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
if (ioc & IO_IN) {
+#ifndef PLATFORM_WINDOWS
CrossThreadChannel::drain (port->selectable());
+#endif
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", ((ARDOUR::Port*)port)->name()));
framepos_t now = _session.engine().sample_time();
#include "ardour/runtime_functions.h"
#include <stdint.h>
+using std::min;
+using std::max;
using namespace ARDOUR;
#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
}
void
-default_find_peaks (const ARDOUR::Sample * buf, pframes_t nframes, float *min, float *max)
+default_find_peaks (const ARDOUR::Sample * buf, pframes_t nframes, float *minf, float *maxf)
{
pframes_t i;
float a, b;
- a = *max;
- b = *min;
+ a = *maxf;
+ b = *minf;
for (i = 0; i < nframes; i++)
{
- a = fmax (buf[i], a);
- b = fmin (buf[i], b);
+ a = max (buf[i], a);
+ b = min (buf[i], b);
}
- *max = a;
- *min = b;
+ *maxf = a;
+ *minf = b;
}
void
--- /dev/null
+/*
+ Copyright (C) 2009 John Emmas
+
+ 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.
+
+*/
+
+#if (defined(PLATFORM_WINDOWS) && !defined(COMPILER_CYGWIN))
+#include <shlobj.h>
+#include <glibmm.h>
+#ifdef COMPILER_MSVC
+#pragma warning(disable:4996)
+#endif
+#else
+#include <glib.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <ardour/msvc_libardour.h>
+
+namespace ARDOUR {
+
+//***************************************************************
+//
+// placeholder_for_non_msvc_specific_function()
+//
+// Description
+//
+// Returns:
+//
+// On Success:
+//
+// On Failure:
+//
+/* LIBARDOUR_API char* LIBARDOUR_APICALLTYPE
+ placeholder_for_non_msvc_specific_function()
+{
+char *pRet = buffer;
+
+ return (pRet);
+}
+*/
+
+} // namespace ARDOUR
+
+#ifdef COMPILER_MSVC
+
+#include <errno.h>
+
+namespace ARDOUR {
+
+//***************************************************************
+//
+// symlink()
+//
+// Emulates POSIX symlink() but creates a Windows shortcut. To
+// create a Windows shortcut the supplied shortcut name must end
+// in ".lnk"
+// Note that you can only create a shortcut in a folder for which
+// you have appropriate access rights. Note also that the folder
+// must already exist. If it doesn't exist or if you don't have
+// sufficient access rights to it, symlink() will generate an
+// error (in common with its POSIX counterpart).
+//
+// Returns:
+//
+// On Success: Zero
+// On Failure: -1 ('errno' will contain the specific error)
+//
+LIBARDOUR_API int LIBARDOUR_APICALLTYPE
+symlink(const char *dest, const char *shortcut, const char *working_directory /*= NULL */)
+{
+IShellLinkA *pISL = NULL;
+IPersistFile *ppf = NULL;
+int ret = (-1);
+
+ if ((NULL == dest) || (NULL == shortcut) || (strlen(shortcut) < 5) || (strlen(dest) == 0))
+ _set_errno(EINVAL);
+ else if ((strlen(shortcut) > _MAX_PATH) || (strlen(dest) > _MAX_PATH))
+ _set_errno(ENAMETOOLONG);
+ else if (Glib::file_test(shortcut, Glib::FILE_TEST_EXISTS))
+ _set_errno(EEXIST);
+ else
+ {
+ HRESULT hRet = 0;
+
+ if (SUCCEEDED (hRet = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pISL)))
+ {
+ if (SUCCEEDED (pISL->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
+ {
+ char sc_path_lower_case[_MAX_PATH];
+ WCHAR shortcut_path[_MAX_PATH];
+
+ // Fail if the path isn't a shortcut
+ strcpy(sc_path_lower_case, shortcut);
+ strlwr(sc_path_lower_case);
+ const char *p = strlen(sc_path_lower_case) + sc_path_lower_case - 4;
+
+ if (0 == strcmp(p, ".lnk"))
+ {
+ HRESULT hr;
+
+ // We're apparently been given valid Windows shortcut name
+ MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, shortcut, -1, shortcut_path, _MAX_PATH);
+
+ // Create the shortcut
+ if (FAILED (hr = ppf->Load(shortcut_path, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE)))
+ hr = ppf->Save(shortcut_path, TRUE);
+
+ if (S_OK == hr)
+ {
+ // Set its target path
+ if (S_OK == pISL->SetPath(dest))
+ {
+ // Set its working directory
+ if (working_directory)
+ p = working_directory;
+ else
+ p = "";
+
+ if (S_OK == pISL->SetWorkingDirectory(p))
+ {
+ // Set its 'Show' command
+ if (S_OK == pISL->SetShowCmd(SW_SHOWNORMAL))
+ {
+ // And finally, set its icon to the same file as the target.
+ // For the time being, don't fail if the target has no icon.
+ if (Glib::file_test(dest, Glib::FILE_TEST_IS_DIR))
+ pISL->SetIconLocation("%SystemRoot%\\system32\\shell32.dll", 1);
+ else
+ pISL->SetIconLocation(dest, 0);
+
+ if (S_OK == ppf->Save(shortcut_path, FALSE))
+ {
+ Sleep(1500);
+
+ ret = 0;
+ // _set_errno(0);
+ }
+ else
+ _set_errno(EACCES);
+ }
+ else
+ _set_errno(EACCES);
+ }
+ else
+ _set_errno(EACCES);
+ }
+ else
+ _set_errno(EACCES);
+ }
+ else
+ _set_errno(EBADF);
+ }
+ else
+ _set_errno(EACCES);
+ }
+ else
+ _set_errno(EBADF);
+ }
+ else
+ {
+ if (E_POINTER == hRet)
+ _set_errno(EINVAL);
+ else
+ _set_errno(EIO);
+ }
+ }
+
+ return (ret);
+}
+
+
+//***************************************************************
+//
+// readlink()
+//
+// Emulates POSIX readlink() but using Windows shortcuts
+// Doesn't (currently) resolve shortcuts to shortcuts. This would
+// be quite simple to incorporate but we'd need to check for
+// recursion (i.e. a shortcut that points to an earlier shortcut
+// in the same chain).
+//
+// Returns:
+//
+// On Success: Zero
+// On Failure: -1 ('errno' will contain the specific error)
+//
+LIBARDOUR_API int LIBARDOUR_APICALLTYPE
+readlink(const char *__restrict shortcut, char *__restrict buf, size_t bufsize)
+{
+IShellLinkA *pISL = NULL;
+IPersistFile *ppf = NULL;
+int ret = (-1);
+
+ if ((NULL == shortcut) || (NULL == buf) || (strlen(shortcut) < 5) || (bufsize == 0))
+ _set_errno(EINVAL);
+ else if ((bufsize > _MAX_PATH) || (strlen(shortcut) > _MAX_PATH))
+ _set_errno(ENAMETOOLONG);
+ else
+ {
+ HRESULT hRet = 0;
+
+ if (SUCCEEDED (hRet = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pISL)))
+ {
+ if (SUCCEEDED (pISL->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
+ {
+ char target_path[_MAX_PATH];
+ WCHAR shortcut_path[_MAX_PATH];
+
+ // Fail if the path isn't a shortcut
+ strcpy(target_path, shortcut); // Use 'target_path' temporarily
+ strlwr(target_path);
+ const char *p = strlen(target_path) + target_path - 4;
+
+ if (0 == strcmp(p, ".lnk"))
+ {
+ // We're apparently pointing to a valid Windows shortcut
+ MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, shortcut, -1, shortcut_path, _MAX_PATH);
+
+ // Load the shortcut into our persistent file
+ if (SUCCEEDED (ppf->Load(shortcut_path, 0)))
+ {
+ // Read the target information from the shortcut object
+ if (S_OK == (pISL->GetPath (target_path, _MAX_PATH, NULL, SLGP_UNCPRIORITY)))
+ {
+ strncpy(buf, target_path, bufsize);
+ ret = ((ret = strlen(buf)) > bufsize) ? bufsize : ret;
+ // _set_errno(0);
+ }
+ else
+ _set_errno(EACCES);
+ }
+ else
+ _set_errno(EBADF);
+ }
+ else
+ _set_errno(EINVAL);
+ }
+ else
+ _set_errno(EBADF);
+ }
+ else
+ {
+ if (E_POINTER == hRet)
+ _set_errno(EINVAL);
+ else
+ _set_errno(EIO);
+ }
+
+ if (ppf)
+ ppf->Release();
+
+ if (pISL)
+ pISL->Release();
+ }
+
+ return (ret);
+}
+
+} // namespace ARDOUR
+
+#endif // COMPILER_MSVC
*/
#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/audioengine.h"
#include "ardour/debug.h"
#include "ardour/session.h"
#include "ardour/slave.h"
+#include <glibmm/timer.h>
+
#include "i18n.h"
using namespace std;
do {
if (tries == 10) {
error << _("MTC Slave: atomic read of current time failed, sleeping!") << endmsg;
- usleep (20);
+ Glib::usleep (20);
tries = 0;
}
*st = current;
* when a full TC has been received
* OR on locate */
void
-MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now)
+MTC_Slave::update_mtc_time (const MIDI::byte *msg, bool was_full, framepos_t now)
{
busy_guard1++;
to use a timestamp indicating when this MTC time was received. example: when we received
a locate command via MMC.
*/
-
+#ifdef COMPILER_MSVC
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", ::pthread_self().p));
+#else
DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", ::pthread_self()));
+#endif
TimecodeFormat tc_format;
bool reset_tc = true;
/* 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++;
#include "ardour/debug.h"
#include "ardour/panner_manager.h"
+
#include "ardour/panner_search_path.h"
#include "i18n.h"
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);
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) {
PannerInfo*
PannerManager::get_descriptor (string path)
{
- void *module;
+ Glib::Module* module = new Glib::Module(path);
PannerInfo* info = 0;
PanPluginDescriptor *descriptor = 0;
PanPluginDescriptor* (*dfunc)(void);
- const char *errstr;
+ void* func = 0;
- if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
- error << string_compose(_("PannerManager: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
+ if (!module) {
+ error << string_compose(_("PannerManager: cannot load module \"%1\" (%2)"), path,
+ Glib::Module::get_last_error()) << endmsg;
+ delete module;
return 0;
}
- dfunc = (PanPluginDescriptor* (*)(void)) dlsym (module, "panner_descriptor");
-
- if ((errstr = dlerror()) != 0) {
+ if (!module->get_symbol("panner_descriptor", func)) {
error << string_compose(_("PannerManager: module \"%1\" has no descriptor function."), path) << endmsg;
- error << errstr << endmsg;
- dlclose (module);
+ error << Glib::Module::get_last_error() << endmsg;
+ delete module;
return 0;
}
+ dfunc = (PanPluginDescriptor* (*)(void))func;
descriptor = dfunc();
+
if (descriptor) {
info = new PannerInfo (*descriptor, module);
} else {
- dlclose (module);
+ delete module;
}
return info;
namespace ARDOUR {
-SearchPath
+Searchpath
panner_search_path ()
{
- SearchPath spath(user_config_directory ());
+ Searchpath spath(user_config_directory ());
spath += ardour_dll_directory ();
spath.add_subdirectory_to_paths(panner_dir_name);
- spath += SearchPath(Glib::getenv(panner_env_variable_name));
+ spath += Searchpath(Glib::getenv(panner_env_variable_name));
return spath;
}
*/
+#ifdef COMPILER_MSVC
+#include <ardourext/float_cast.h>
+#endif
#include "ardour/pcm_utils.h"
-
#include <cmath>
using namespace std;
freeze ();
/* add the added regions */
- for (RegionListProperty::ChangeContainer::iterator i = change.added.begin(); i != change.added.end(); ++i) {
+ for (RegionListProperty::ChangeContainer::const_iterator i = change.added.begin(); i != change.added.end(); ++i) {
add_region_internal ((*i), (*i)->position());
}
/* remove the removed regions */
- for (RegionListProperty::ChangeContainer::iterator i = change.removed.begin(); i != change.removed.end(); ++i) {
+ for (RegionListProperty::ChangeContainer::const_iterator i = change.removed.begin(); i != change.removed.end(); ++i) {
remove_region (*i);
}
{
RegionReadLock rlock (const_cast<Playlist*> (this));
- for (set<boost::shared_ptr<Region> >::iterator r = all_regions.begin(); r != all_regions.end(); ++r) {
+ for (set<boost::shared_ptr<Region> >::const_iterator r = all_regions.begin(); r != all_regions.end(); ++r) {
if ((*r)->uses_source (src)) {
return true;
}
{
/* searches all regions ever added to this playlist */
- for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) {
+ for (set<boost::shared_ptr<Region> >::const_iterator i = all_regions.begin(); i != all_regions.end(); ++i) {
if ((*i)->id() == id) {
return *i;
}
#include <cstdlib>
#include <cstdio> // so libraptor doesn't complain
#include <cmath>
+#ifndef COMPILER_MSVC
#include <dirent.h>
+#endif
#include <sys/stat.h>
#include <cerrno>
#include <utility>
+#ifdef HAVE_LRDF
#include <lrdf.h>
+#endif
#include "pbd/compose.h"
#include "pbd/error.h"
#include <sys/types.h>
#include <cstdio>
-#include <lrdf.h>
-#include <dlfcn.h>
#include <cstdlib>
#include <fstream>
+#ifdef HAVE_LRDF
+#include <lrdf.h>
+#endif
+
#ifdef WINDOWS_VST_SUPPORT
#include "fst.h"
#include "pbd/basename.h"
#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"
#include "ardour/plugin_manager.h"
#include "ardour/rc_configuration.h"
+#include "ardour/ladspa_search_path.h"
+
#ifdef LV2_SUPPORT
#include "ardour/lv2_plugin.h"
#endif
#include "i18n.h"
+#include "ardour/debug.h"
+
using namespace ARDOUR;
using namespace PBD;
using namespace std;
}
#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"))) {
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" */
+ DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
- return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
-}
-
-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*/)
void
PluginManager::add_presets(string domain)
{
-
+#ifdef HAVE_LRDF
PathScanner scanner;
vector<string *> *presets;
vector<string *>::iterator x;
vector_delete (presets);
}
+#endif
}
void
PluginManager::add_lrdf_data (const string &path)
{
+#ifdef HAVE_LRDF
PathScanner scanner;
vector<string *>* rdf_files;
vector<string *>::iterator x;
vector_delete (rdf_files);
}
+#endif
}
int
PluginManager::ladspa_discover (string path)
{
- void *module;
+ 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;
- const char *errstr;
+ void* func = 0;
- if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
- error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
+ if (!module) {
+ error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
+ path, Glib::Module::get_last_error()) << endmsg;
return -1;
}
- dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
- if ((errstr = dlerror()) != 0) {
+ if (!module.get_symbol("ladspa_descriptor", func)) {
error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
- error << errstr << endmsg;
- dlclose (module);
+ error << Glib::Module::get_last_error() << endmsg;
return -1;
}
+ 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;
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
string
PluginManager::get_ladspa_category (uint32_t plugin_id)
{
+#ifdef HAVE_LRDF
char buf[256];
lrdf_statement pattern;
} else {
return label;
}
+#else
+ return ("Unknown");
+#endif
}
#ifdef LV2_SUPPORT
#include "libardour-config.h"
#endif
+#ifndef PLATFORM_WINDOWS
#include <jack/weakjack.h> // so that we can test for new functions at runtime
+#endif
#include "pbd/compose.h"
#include "pbd/error.h"
bool
PortInsert::configure_io (ChanCount in, ChanCount out)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
/* for an insert, processor input corresponds to IO output, and vice versa */
// if some of the names don't have a number as posfix, compare as strings
- if (last_digit_position_a == aname.size() or last_digit_position_b == bname.size()) {
+ if (last_digit_position_a == aname.size() || last_digit_position_b == bname.size()) {
return aname < bname;
}
RCConfiguration::load_state ()
{
std::string rcfile;
- struct stat statbuf;
+ GStatBuf statbuf;
/* load system configuration first */
uint32_t number;
string::size_type len = old.length() + 64;
string remainder;
- char buf[len];
+ std::vector<char> buf(len);
if ((last_period = old.find_last_of ('.')) == string::npos) {
number++;
- snprintf (buf, len, "%s%" PRIu32 "%s", old.substr (0, last_period + 1).c_str(), number, remainder.c_str());
- sbuf = buf;
+ snprintf (&buf[0], len, "%s%" PRIu32 "%s", old.substr (0, last_period + 1).c_str(), number, remainder.c_str());
+ sbuf = &buf[0];
if (region_name_map.find (sbuf) == region_name_map.end ()) {
break;
}
if (number != (UINT_MAX-1)) {
- return buf;
+ return &buf[0];
}
error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
using namespace ARDOUR;
using namespace PBD;
+#ifdef PLATFORM_WINDOWS
+const uint32_t ResampledImportableSource::blocksize = 524288U;
+#else
const uint32_t ResampledImportableSource::blocksize = 16384U;
+#endif
ResampledImportableSource::ResampledImportableSource (boost::shared_ptr<ImportableSource> src, framecnt_t rate, SrcQuality srcq)
: source (src)
int
Route::configure_processors (ProcessorStreams* err)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
if (!_in_configure_processors) {
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
int
Route::configure_processors_unlocked (ProcessorStreams* err)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
if (_in_configure_processors) {
return 0;
{
const FedBy& fed_by (other->fed_by());
- for (FedBy::iterator f = fed_by.begin(); f != fed_by.end(); ++f) {
+ for (FedBy::const_iterator f = fed_by.begin(); f != fed_by.end(); ++f) {
boost::shared_ptr<Route> sr = f->r.lock();
if (sr && (sr.get() == this)) {
#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"
}
}
-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 {
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;
}
}
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;
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.
}
}
- 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;
}
}
*/
-#include <algorithm>
-#include <string>
-#include <cmath>
-#include <cerrno>
-#include <unistd.h>
-#include <fcntl.h>
-#include <poll.h>
-
-#include <glibmm/threads.h>
-
#include "pbd/error.h"
#include "pbd/pthread_utils.h"
#include "pbd/stacktrace.h"
#include "pbd/error.h"
#include "pbd/enumwriter.h"
#include "pbd/stacktrace.h"
+#include "pbd/pthread_utils.h"
#include "ardour/debug.h"
#include "ardour/session_event.h"
{
CrossThreadPool* p = pool->per_thread_pool ();
SessionEvent* ev = static_cast<SessionEvent*> (p->alloc ());
- DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("%1 Allocating SessionEvent from %2 ev @ %3\n", pthread_self(), p->name(), ev));
+ DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("%1 Allocating SessionEvent from %2 ev @ %3\n", pthread_name(), p->name(), ev));
#ifndef NDEBUG
if (DEBUG::SessionEvents & PBD::debug_bits) {
stacktrace (cerr, 40);
DEBUG_TRACE (DEBUG::SessionEvents, string_compose (
"%1 Deleting SessionEvent @ %2 ev thread pool = %3 ev pool = %4\n",
- pthread_self(), ev, p->name(), ev->own_pool->name()
+ pthread_name(), ev, p->name(), ev->own_pool->name()
));
#ifndef NDEBUG
using namespace std;
using namespace ARDOUR;
-using namespace MIDI;
using namespace PBD;
using namespace Timecode;
#include <cerrno>
#include <cassert>
#include <unistd.h>
-#include <fcntl.h>
-#include <poll.h>
#include <boost/shared_ptr.hpp>
#include "pbd/error.h"
#include "pbd/pthread_utils.h"
+#include "pbd/timersub.h"
#include "timecode/time.h"
* @param t time to send.
*/
int
-Session::send_full_time_code (framepos_t const t, pframes_t nframes)
+Session::send_full_time_code (framepos_t const t, MIDI::pframes_t nframes)
{
/* This function could easily send at a given frame offset, but would
* that be useful? Does ardour do sub-block accurate locating? [DR] */
* earlier already this cycle by send_full_time_code)
*/
int
-Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_frame, pframes_t nframes)
+Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_frame, ARDOUR::pframes_t nframes)
{
if (_engine.freewheeling() || !_send_qf_mtc || transmitting_timecode_time.negative || (next_quarter_frame_to_send < 0)) {
// cerr << "(MTC) Not sending MTC\n";
assert (msg_time < end_frame);
/* convert from session frames back to JACK frames using the transport speed */
- pframes_t const out_stamp = (msg_time - start_frame) / _transport_speed;
+ ARDOUR::pframes_t const out_stamp = (msg_time - start_frame) / _transport_speed;
assert (out_stamp < nframes);
MidiBuffer& mb (_midi_ports->mtc_output_port()->get_midi_buffer(nframes));
{
Glib::Threads::Mutex::Lock lm (lock);
- for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ for (List::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
s.push_back (*i);
}
- for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+ for (List::const_iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
s.push_back (*i);
}
}
Glib::Threads::Mutex::Lock lm (lock);
uint32_t cnt = 0;
- for (List::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ for (List::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
cnt += (*i)->region_use_count (region);
}
- for (List::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
+ for (List::const_iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
cnt += (*i)->region_use_count (region);
}
#include <unistd.h>
#include <sys/stat.h>
#include <climits>
-#include <fcntl.h>
-#include <poll.h>
#include <signal.h>
-#include <sys/mman.h>
#include <sys/time.h>
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
-#else
+#endif
+
+#ifdef __APPLE__
#include <sys/param.h>
#include <sys/mount.h>
#endif
#include "pbd/enumwriter.h"
#include "pbd/error.h"
#include "pbd/file_utils.h"
+#include "pbd/pathexpand.h"
#include "pbd/pathscanner.h"
#include "pbd/pthread_utils.h"
#include "pbd/stacktrace.h"
#include "pbd/convert.h"
#include "pbd/clear_dir.h"
+#include "pbd/localtime_r.h"
#include "ardour/amp.h"
#include "ardour/audio_diskstream.h"
string
Session::raid_path () const
{
- SearchPath raid_search_path;
+ Searchpath raid_search_path;
for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
raid_search_path += (*i).path;
session_dirs.clear ();
- SearchPath search_path(path);
- SearchPath sound_search_path;
- SearchPath midi_search_path;
+ Searchpath search_path(path);
+ Searchpath sound_search_path;
+ Searchpath midi_search_path;
- for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
+ for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
sp.path = *i;
sp.blocks = 0; // not needed
session_dirs.push_back (sp);
} 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;
_total_free_4k_blocks_uncertain = true;
}
}
+#elif defined (COMPILER_MSVC)
+ vector<string> scanned_volumes;
+ vector<string>::iterator j;
+ vector<space_and_path>::iterator i;
+ DWORD nSectorsPerCluster, nBytesPerSector,
+ nFreeClusters, nTotalClusters;
+ char disk_drive[4];
+ bool volume_found;
+
+ _total_free_4k_blocks = 0;
+
+ for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
+ strncpy (disk_drive, (*i).path.c_str(), 3);
+ disk_drive[3] = 0;
+ strupr(disk_drive);
+
+ volume_found = false;
+ if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
+ {
+ int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
+ int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
+ i->blocks = (uint32_t)(nFreeBytes / 4096);
+
+ for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
+ if (0 == j->compare(disk_drive)) {
+ volume_found = true;
+ break;
+ }
+ }
+
+ if (!volume_found) {
+ scanned_volumes.push_back(disk_drive);
+ _total_free_4k_blocks += i->blocks;
+ }
+ }
+ }
+
+ if (0 == _total_free_4k_blocks) {
+ strncpy (disk_drive, path().c_str(), 3);
+ disk_drive[3] = 0;
+
+ if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
+ {
+ int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
+ int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
+ _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
+ }
+ }
#endif
}
}
static bool
-state_file_filter (const string &str, void */*arg*/)
+state_file_filter (const string &str, void* /*arg*/)
{
return (str.length() > strlen(statefile_suffix) &&
str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
}
static bool
-accept_all_audio_files (const string& path, void */*arg*/)
+accept_all_audio_files (const string& path, void* /*arg*/)
{
if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
return false;
}
static bool
-accept_all_midi_files (const string& path, void */*arg*/)
+accept_all_midi_files (const string& path, void* /*arg*/)
{
if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
return false;
}
static bool
-accept_all_state_files (const string& path, void */*arg*/)
+accept_all_state_files (const string& path, void* /*arg*/)
{
if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
return false;
bool used;
string spath;
int ret = -1;
+ string tmppath1;
+ string tmppath2;
_state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
i = tmp;
}
- char tmppath1[PATH_MAX+1];
- char tmppath2[PATH_MAX+1];
-
if (candidates) {
for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
- if (realpath(spath.c_str(), tmppath1) == 0) {
- error << string_compose (_("Cannot expand path %1 (%2)"),
- spath, strerror (errno)) << endmsg;
- continue;
- }
-
- if (realpath((*i).c_str(), tmppath2) == 0) {
- error << string_compose (_("Cannot expand path %1 (%2)"),
- (*i), strerror (errno)) << endmsg;
- continue;
- }
+ tmppath1 = canonical_path (spath);
+ tmppath2 = canonical_path ((*i));
- if (strcmp(tmppath1, tmppath2) == 0) {
+ if (tmppath1 == tmppath2) {
used = true;
break;
}
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;
*/
+#ifndef COMPILER_MSVC
#include <stdbool.h>
+#endif
#include <cstdio>
#include "ardour/session.h"
if (effect && effect->user) {
plug = (VSTPlugin *) (effect->user);
session = &plug->session();
+#ifdef COMPILER_MSVC
+ SHOW_CALLBACK ("am callback 0x%x, opcode = %d, plugin = \"%s\" ", (int) pthread_self().p, opcode, plug->name());
+#else
SHOW_CALLBACK ("am callback 0x%x, opcode = %d, plugin = \"%s\" ", (int) pthread_self(), opcode, plug->name());
+#endif
} else {
plug = 0;
session = 0;
+#ifdef COMPILER_MSVC
+ SHOW_CALLBACK ("am callback 0x%x, opcode = %d", (int) pthread_self().p, opcode);
+#else
SHOW_CALLBACK ("am callback 0x%x, opcode = %d", (int) pthread_self(), opcode);
+#endif
}
switch(opcode){
#include "pbd/stl_delete.h"
#include "pbd/strsplit.h"
+#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include "evoral/Control.hpp"
SMFSource::~SMFSource ()
{
if (removable()) {
- unlink (_path.c_str());
+ ::g_unlink (_path.c_str());
}
}
*/
+#ifndef COMPILER_MSVC
#include <strings.h>
+#endif
#include <map>
#include <sndfile.h>
return per_channel * sf_info.channels;
}
-uint
+uint32_t
SndFileImportableSource::channels () const
{
return sf_info.channels;
#include <climits>
#include <cstdarg>
-#include <pwd.h>
-#include <sys/utsname.h>
#include <sys/stat.h>
+#ifdef PLATFORM_WINDOWS
+#include <glibmm/convert.h>
+#endif
#include <glibmm/miscutils.h>
#include "ardour/sndfilesource.h"
int
SndFileSource::open ()
{
- _descriptor = new SndFileDescriptor (_path, writable(), &_info);
+ string path_to_open;
+
+#ifdef PLATFORM_WINDOWS
+ path_to_open = Glib::locale_from_utf8(_path);
+#else
+ path_to_open = _path;
+#endif
+
+ _descriptor = new SndFileDescriptor (path_to_open.c_str(), writable(), &_info);
_descriptor->Closed.connect_same_thread (file_manager_connection, boost::bind (&SndFileSource::file_closed, this));
SNDFILE* sf = _descriptor->allocate ();
if (sf == 0) {
- char errbuf[256];
+ char errbuf[1024];
sf_error_str (0, errbuf, sizeof (errbuf) - 1);
#ifndef HAVE_COREAUDIO
/* if we have CoreAudio, we will be falling back to that if libsndfile fails,
so we don't want to see this message.
*/
- cerr << "failed to open " << _path << " with name " << _name << endl;
+ cerr << "failed to open " << path_to_open << " with name " << _name << endl;
error << string_compose(_("SndFileSource: cannot open file \"%1\" for %2 (%3)"),
- _path, (writable() ? "read+write" : "reading"), errbuf) << endmsg;
+ path_to_open, (writable() ? "read+write" : "reading"), errbuf) << endmsg;
#endif
return -1;
}
if (!_broadcast_info->write_to_file (sf)) {
error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
- _path, _broadcast_info->get_error())
+ path_to_open, _broadcast_info->get_error())
<< endmsg;
_flags = Flag (_flags & ~Broadcast);
delete _broadcast_info;
return r;
}
+void
+SndFileSource::flush ()
+{
+ if (!_open) {
+ warning << string_compose (_("attempt to flush an un-opened audio file source (%1)"), _path) << endmsg;
+ return;
+ }
+
+ if (!writable()) {
+ warning << string_compose (_("attempt to flush a non-writable audio file source (%1)"), _path) << endmsg;
+ return;
+ }
+
+ SNDFILE* sf = _descriptor->allocate ();
+ if (sf == 0) {
+ error << string_compose (_("could not allocate file %1 to flush contents"), _path) << endmsg;
+ return;
+ }
+
+ // Hopefully everything OK
+ sf_write_sync (sf);
+ _descriptor->release ();
+}
+
int
SndFileSource::setup_broadcast_info (framepos_t /*when*/, struct tm& now, time_t /*tnow*/)
{
} else if (xfade < xfade_frames) {
- gain_t in[xfade];
- gain_t out[xfade];
+ std::vector<gain_t> in(xfade);
+ std::vector<gain_t> out(xfade);
/* short xfade, compute custom curve */
- compute_equal_power_fades (xfade, in, out);
+ compute_equal_power_fades (xfade, &in[0], &out[0]);
for (framecnt_t n = 0; n < xfade; ++n) {
xfade_buf[n] = (xfade_buf[n] * out[n]) + (fade_data[n] * in[n]);
#include <sys/stat.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <poll.h>
#include <float.h>
#include <cerrno>
#include <ctime>
// use 64 byte prefetch for quadruple quads
while (nframes >= 16) {
+#ifdef COMPILER_MSVC
+ _mm_prefetch(((char*)buf+64), 0); // A total guess! Assumed to be eqivalent to
+#else // the line below but waiting to be tested !!
__builtin_prefetch(buf+64,0,0);
-
+#endif
work = _mm_load_ps(buf);
current_min = _mm_min_ps(current_min, work);
current_max = _mm_max_ps(current_max, work);
namespace ARDOUR {
-SearchPath
+Searchpath
template_search_path ()
{
- SearchPath spath (ardour_data_search_path());
+ Searchpath spath (ardour_data_search_path());
spath.add_subdirectory_to_paths(templates_dir_name);
return spath;
}
-SearchPath
+Searchpath
route_template_search_path ()
{
- SearchPath spath (ardour_data_search_path());
+ Searchpath spath (ardour_data_search_path());
spath.add_subdirectory_to_paths(route_templates_dir_name);
return spath;
}
}
static bool
-template_filter (const string &str, void */*arg*/)
+template_filter (const string &str, void* /*arg*/)
{
if (!Glib::file_test (str, Glib::FILE_TEST_IS_DIR)) {
return false;
}
static bool
-route_template_filter (const string &str, void */*arg*/)
+route_template_filter (const string &str, void* /*arg*/)
{
if (str.find (template_suffix) == str.length() - strlen (template_suffix)) {
return true;
{
vector<string *> *templates;
PathScanner scanner;
- SearchPath spath (template_search_path());
+ Searchpath spath (template_search_path());
templates = scanner (spath.to_string(), template_filter, 0, true, true);
{
vector<string *> *templates;
PathScanner scanner;
- SearchPath spath (route_template_search_path());
+ Searchpath spath (route_template_search_path());
templates = scanner (spath.to_string(), route_template_filter, 0, false, true);
--- /dev/null
+
+#include <stdexcept>
+
+#ifdef PLATFORM_WINDOWS
+#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;
+}
+
+bool
+get_default_jack_command_line (std::string& command_line)
+{
+ cout << endl;
+
+ JackCommandLineOptions options;
+
+ CPPUNIT_ASSERT (get_jack_default_server_path (options.server_path));
+
+ get_jack_default_audio_driver_name (options.driver);
+
+
+ // 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
+ return get_jack_command_line_string (options, command_line);
+
+}
+
+void
+JackUtilsTest::test_config ()
+{
+ std::string config_path(get_jack_server_user_config_file_path());
+
+ cout << "Jack server config file path: " << config_path << endl;
+
+ std::string command_line;
+
+ CPPUNIT_ASSERT (get_default_jack_command_line (command_line));
+
+ CPPUNIT_ASSERT (write_jack_config_file (config_path, command_line));
+}
+
+
+void
+JackUtilsTest::test_command_line ()
+{
+ string command_line;
+
+ // this at least should create a valid jack command line
+ CPPUNIT_ASSERT (get_default_jack_command_line (command_line));
+
+ cout << "Default JACK command line: " << command_line << endl;
+}
--- /dev/null
+
+#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_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 ();
+};
for (framecnt_t i = 1; i<= 100 * period_size; i++) {
// simulate jitter
- framecnt_t input_delta = framecnt_t (one_ppqn_in_frames + 0.1 * (double(random()) / double (RAND_MAX)) * one_ppqn_in_frames);
+ framecnt_t input_delta = framecnt_t (one_ppqn_in_frames + 0.1 * (double(g_random_int()) / double (RAND_MAX)) * one_ppqn_in_frames);
if (i % input_delta == 0) {
update_midi_clock (*parser, start_time + i);
--- /dev/null
+#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);
+ }
+
+
+}
--- /dev/null
+#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 ();
+};
-// this is included first to avoid SearchPath definition on windows
+// this is included first to avoid Searchpath definition on windows
#include "test_common.h"
#include "pbd/file_utils.h"
using namespace std;
-PBD::SearchPath
+PBD::Searchpath
test_search_path ()
{
-#ifdef WIN32
+#ifdef PLATFORM_WINDOWS
std::string wsp(g_win32_get_package_installation_directory_of_module(NULL));
return Glib::build_filename (wsp, "ardour_testdata");
#else
#include "pbd/search_path.h"
-PBD::SearchPath test_search_path ();
+PBD::Searchpath test_search_path ();
std::string new_test_output_dir (std::string prefix = "");
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
+#ifndef COMPILER_MSVC
#include <dirent.h>
+#endif
#include <errno.h>
#include <regex.h>
{
Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
- float *ins[_plugin->numInputs];
- float *outs[_plugin->numOutputs];
+ // VC++ doesn't support this C99 extension. Use alloca instead of dynamic array (rather than std::vector which allocs on the heap)
+ float** ins = (float**)alloca(_plugin->numInputs*sizeof(float*));
+ float** outs = (float**)alloca(_plugin->numInputs*sizeof(float*));
int32_t i;
const uint32_t nbufs = bufs.count().n_audio();
}
/* we already know it can support processReplacing */
- _plugin->processReplacing (_plugin, ins, outs, nframes);
+ _plugin->processReplacing (_plugin, &ins[0], &outs[0], nframes);
return 0;
}
#include "ardour/worker.h"
#include "pbd/error.h"
+#include <glibmm/timer.h>
+
namespace ARDOUR {
Worker::Worker(Workee* workee, uint32_t ring_size)
continue;
}
while (!verify_message_completeness(_requests)) {
- ::usleep(2000);
+ Glib::usleep(2000);
if (_exit) {
return;
}
from waflib.extras import autowaf as autowaf
from waflib import Options
import os
+import sys
import re
import subprocess
import sys
'io_processor.cc',
'kmeterdsp.cc',
'ladspa_plugin.cc',
+ 'ladspa_search_path.cc',
'location.cc',
'location_importer.cc',
'ltc_slave.cc',
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')
+ if Options.options.dist_target == 'auto':
+ if re.search ("linux", sys.platform) != None:
+ autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA')
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',
create_ardour_test_program(bld, obj.includes, 'framepos_minus_beats', 'test_framepos_minus_beats', ['test/framepos_minus_beats_test.cc'])
create_ardour_test_program(bld, obj.includes, 'playlist_equivalent_regions', 'test_playlist_equivalent_regions', ['test/playlist_equivalent_regions_test.cc'])
create_ardour_test_program(bld, obj.includes, 'playlist_layering', 'test_playlist_layering', ['test/playlist_layering_test.cc'])
+ create_ardour_test_program(bld, obj.includes, 'plugins_test', 'test_plugins', ['test/plugins_test.cc'])
create_ardour_test_program(bld, obj.includes, 'region_naming', 'test_region_naming', ['test/region_naming_test.cc'])
create_ardour_test_program(bld, obj.includes, 'control_surface', 'test_control_surfaces', ['test/control_surfaces_test.cc'])
create_ardour_test_program(bld, obj.includes, 'mtdm_test', 'test_mtdm', ['test/mtdm_test.cc'])
test/framepos_minus_beats_test.cc
test/playlist_equivalent_regions_test.cc
test/playlist_layering_test.cc
+ test/plugins_test.cc
test/region_naming_test.cc
test/control_surfaces_test.cc
test/mtdm_test.cc
#ifndef AUDIOGRAPHER_BROADCAST_INFO_H
#define AUDIOGRAPHER_BROADCAST_INFO_H
+#include <stdint.h>
+
#include <string>
#include <ctime>
#ifdef __GNUC__
#include <cxxabi.h>
+#include <cstdlib>
#endif
namespace AudioGrapher
#include <cstdio>
#include <string>
+#include <glib.h>
+#include <glib/gstdio.h>
+
#include "sndfile_writer.h"
#include "sndfile_reader.h"
/// \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)
{}
switch (bit_depth) {
case GDither8bit:
- o8[i] = (u_int8_t) (clamped * post_scale);
+ o8[i] = (uint8_t) (clamped * post_scale);
break;
case GDither16bit:
o16[i] = (int16_t) (clamped * post_scale);
break;
}
- clamped = rintf(tmp);
+ clamped = (double)lrintf(tmp);
if (clamped > clamp_u) {
clamped = clamp_u;
} else if (clamped < clamp_l) {
static void
snprintf_bounded_null_filled (char* target, size_t target_size, char const * fmt, ...)
{
- char buf[target_size+1];
+ char *buf = (char*)alloca(target_size+1);
va_list ap;
va_start (ap, fmt);
void testProcess()
{
- uint channels = 2;
+ uint32_t channels = 2;
file.reset (new TmpFile<float>(SF_FORMAT_WAV | SF_FORMAT_FLOAT, channels, 44100));
AllocatingProcessContext<float> c (random_data, frames, channels);
c.set_flag (ProcessContext<float>::EndOfInput);
#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().c_str(), 1);
+ setenv ("PATH", Searchpath(dirs).to_string().c_str(), 1);
#else
/* silence a compiler unused variable warning */
(void) dirs;
server_dir_paths.push_back (Glib::path_get_dirname (execpath));
#endif
- SearchPath sp(string(g_getenv("PATH")));
+ Searchpath sp(string(g_getenv("PATH")));
#ifdef WIN32
gchar *install_dir = g_win32_get_package_installation_directory_of_module (NULL);
#!/usr/bin/env python
from waflib.extras import autowaf as autowaf
+from waflib import Options
import os
import sys
import re
autowaf.set_options(opt)
def configure(conf):
- autowaf.check_pkg(conf, 'jack', uselib_store='JACK', atleast_version='0.121.0')
+ #
+ # PortAudio is currently used to get a list of audio device names.
+ # We should find a better way to do this that doesn't involve this
+ # kind of dependency.
+ #
+ if Options.options.dist_target == 'mingw':
+ autowaf.check_pkg(conf, 'portaudio-2.0', uselib_store='PORTAUDIO',
+ atleast_version='19')
autowaf.configure(conf)
def build(bld):
obj.includes = ['.']
obj.name = 'jack_audiobackend'
obj.target = 'jack_audiobackend'
- obj.uselib = [ 'JACK' ]
+ if Options.options.dist_target == 'mingw':
+ obj.uselib = [ 'JACK', 'PORTAUDIO' ]
+ else:
+ obj.uselib = [ 'JACK' ]
obj.use = 'ardour libpbd'
obj.vnum = JACKBACKEND_VERSION
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3', 'backends')
static gboolean
update_animation_info (gpointer key, gpointer value, gpointer user_data)
{
- (void) user_data;
-
- AnimationInfo *animation_info = value;
+ AnimationInfo *animation_info;
GtkWidget *widget = key;
+ animation_info = value;
+ (void) user_data;
+
g_assert ((widget != NULL) && (animation_info != NULL));
/* remove the widget from the hash table if it is not drawable */
static void
on_checkbox_toggle (GtkWidget *widget, gpointer data)
{
+ AnimationInfo *animation_info;
(void) data;
- AnimationInfo *animation_info = lookup_animation_info (widget);
+ animation_info = lookup_animation_info (widget);
if (animation_info != NULL)
{
const MenuBarParameters *menubar,
int x, int y, int width, int height)
{
- (void) params;
- (void) menubar;
-
/* const CairoColor *light = &colors->shade[0]; */
const CairoColor *dark = &colors->shade[3];
+ (void) params;
+ (void) menubar;
+
cairo_set_line_width (cr, 1);
cairo_translate (cr, x, y+0.5);
const MenuBarParameters *menubar,
int x, int y, int width, int height)
{
- (void) params;
- (void) menubar;
-
CairoColor lower;
cairo_pattern_t *pattern;
+ (void) params;
+ (void) menubar;
+
ge_shade_color (&colors->bg[0], 0.96, &lower);
cairo_translate (cr, x, y);
const SeparatorParameters *separator,
int x, int y, int width, int height)
{
- (void) widget;
-
+ CairoColor hilight;
CairoColor color = colors->shade[3];
- CairoColor hilight;
+
+ (void) widget;
ge_shade_color (&color, 1.4, &hilight);
cairo_save (cr);
const ToolbarParameters *toolbar,
int x, int y, int width, int height)
{
- (void) widget;
-
- const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL];
- const CairoColor *dark = &colors->shade[3];
CairoColor light;
+ const CairoColor *dark;
+ const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL];
+
+ (void) widget;
+ dark = &colors->shade[3];
ge_shade_color (fill, 1.1, &light);
cairo_set_line_width (cr, 1.0);
const ScrollBarParameters *scrollbar,
int x, int y, int width, int height)
{
- (void) widget;
-
- const CairoColor *bg = &colors->shade[2];
- const CairoColor *border = &colors->shade[5];
+ const CairoColor *bg;
CairoColor bg_shade;
- cairo_pattern_t *pattern;
+ cairo_pattern_t *pattern;
+ const CairoColor *border = &colors->shade[5];
+ (void) widget;
+ bg = &colors->shade[2];
ge_shade_color (bg, 0.95, &bg_shade);
cairo_set_line_width (cr, 1);
const WidgetParameters *widget,
int x, int y, int width, int height)
{
+ CairoColor hilight;
+ const CairoColor *dark = &colors->shade[3];
+
(void) widget;
(void) height;
-
- const CairoColor *dark = &colors->shade[3];
- CairoColor hilight;
ge_shade_color (dark, 1.4, &hilight);
const WidgetParameters *widget,
int x, int y, int width, int height)
{
+ const CairoColor *border = &colors->shade[5];
(void) widget;
- const CairoColor *border = &colors->shade[5];
cairo_translate (cr, x, y);
cairo_set_line_width (cr, 1);
/*
const ResizeGripParameters *grip,
int x, int y, int width, int height)
{
- (void) widget;
-
- const CairoColor *dark = &colors->shade[4];
CairoColor hilight;
int lx, ly;
int x_down;
int y_down;
int dots;
-
+ const CairoColor *dark = &colors->shade[4];
+
+ (void) widget;
+
ge_shade_color (dark, 1.5, &hilight);
/* The number of dots fitting into the area. Just hardcoded to 4 right now. */
const CheckboxParameters *checkbox,
int x, int y, int width, int height)
{
- (void) width;
- (void) height;
-
const CairoColor *border;
const CairoColor *dot;
CairoColor shadow;
CairoColor highlight;
cairo_pattern_t *pt;
gboolean inconsistent;
+
gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
+ (void) width;
+ (void) height;
+
inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
draw_bullet |= inconsistent;
const ToolbarParameters *toolbar,
int x, int y, int width, int height)
{
+ CairoColor light;
+ const CairoColor *dark;
+
+ const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL];
+ dark = &colors->shade[3];
+
(void) widget;
(void) width;
(void) height;
-
- const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL];
- const CairoColor *dark = &colors->shade[3];
- CairoColor light;
+
ge_shade_color (fill, 1.1, &light);
cairo_set_line_width (cr, 1.0);
const CheckboxParameters *checkbox,
int x, int y, int width, int height)
{
- (void) width;
- (void) height;
-
const CairoColor *border;
const CairoColor *dot;
CairoColor shadow;
gboolean inconsistent;
gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
+ (void) width;
+ (void) height;
+
inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
draw_bullet |= inconsistent;
const SeparatorParameters *separator,
int x, int y, int width, int height)
{
- (void) widget;
-
- CairoColor color = colors->shade[3];
CairoColor hilight;
+ CairoColor color = colors->shade[3];
+
+ (void) widget;
ge_shade_color (&color, 1.3, &hilight);
cairo_save (cr);
const ToolbarParameters *toolbar,
int x, int y, int width, int height)
{
- (void) widget;
-
- const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL];
- const CairoColor *dark = &colors->shade[3];
CairoColor light;
+ const CairoColor *dark;
+ const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL];
+
+ (void) widget;
+
+ dark = &colors->shade[3];
+
ge_shade_color (fill, toolbar->style == 1 ? 1.1 : 1.05, &light);
cairo_set_line_width (cr, 1.0);
const WidgetParameters *widget,
int x, int y, int width, int height)
{
+ CairoColor hilight;
+ const CairoColor *dark = &colors->shade[3];
+
(void) widget;
(void) height;
- const CairoColor *dark = &colors->shade[3];
- CairoColor hilight;
-
ge_shade_color (dark, 1.3, &hilight);
cairo_set_line_width (cr, 1);
const CheckboxParameters *checkbox,
int x, int y, int width, int height)
{
- (void) width;
- (void) height;
-
const CairoColor *border;
const CairoColor *dot;
CairoColor shadow;
gboolean inconsistent;
gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
+ (void) width;
+ (void) height;
+
inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
draw_bullet |= inconsistent;
GScanner *scanner,
gboolean *retval)
{
- (void) settings;
-
guint token;
+
+ (void) settings;
token = g_scanner_get_next_token(scanner);
token = g_scanner_get_next_token(scanner);
GScanner *scanner,
GdkColor *color)
{
- (void) settings;
-
guint token;
+ (void) settings;
+
/* Skip 'blah_color' */
token = g_scanner_get_next_token(scanner);
GScanner *scanner,
gdouble *val)
{
- (void) settings;
-
guint token;
+ (void) settings;
+
/* Skip 'blah' */
token = g_scanner_get_next_token(scanner);
GScanner *scanner,
guint8 *progressbarstyle)
{
- (void) settings;
-
guint token;
+ (void) settings;
+
/* Skip 'sunkenmenubar' */
token = g_scanner_get_next_token(scanner);
GScanner *scanner,
ClearlooksStyles *style)
{
- (void) settings;
-
guint token;
+ (void) settings;
+
g_assert (CL_NUM_STYLES == CL_STYLE_GUMMY + 1); /* so that people don't forget ;-) */
/* Skip 'style' */
GScanner *scanner,
gchar *name)
{
- (void) settings;
-
guint token;
+ (void) settings;
+
/* Skip option */
token = g_scanner_get_next_token (scanner);
static void
clearlooks_style_draw_option (DRAW_ARGS)
{
- (void) detail;
-
- ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
const ClearlooksColors *colors;
WidgetParameters params;
CheckboxParameters checkbox;
cairo_t *cr;
+ ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
+ (void) detail;
+
CHECK_ARGS
SANITIZE_SIZE
gint y2,
gint x)
{
+ const ClearlooksColors *colors;
+ SeparatorParameters separator;
+ cairo_t *cr;
+
+ ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
+
(void) state_type;
(void) widget;
(void) detail;
-
- ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
- const ClearlooksColors *colors;
- SeparatorParameters separator = { FALSE };
- cairo_t *cr;
+
+ separator.horizontal = FALSE;
CHECK_ARGS
gint x2,
gint y)
{
- (void) state_type;
- (void) widget;
-
- ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
const ClearlooksColors *colors;
cairo_t *cr;
SeparatorParameters separator;
+ ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
+
+ (void) state_type;
+ (void) widget;
CHECK_ARGS
gint width,
gint height)
{
- (void) detail;
-
- ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
- ClearlooksColors *colors = &clearlooks_style->colors;
+ ClearlooksColors *colors;
cairo_t *cr;
WidgetParameters params;
ResizeGripParameters grip;
+ ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
+
+ (void) detail;
+ colors = &clearlooks_style->colors;
CHECK_ARGS
SANITIZE_SIZE
static void
clearlooks_style_draw_tab (DRAW_ARGS)
{
- (void) shadow_type;
- (void) detail;
-
- ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
- ClearlooksColors *colors = &clearlooks_style->colors;
+ ClearlooksColors *colors;
WidgetParameters params;
ArrowParameters arrow;
cairo_t *cr;
+ ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
+
+ (void) shadow_type;
+ (void) detail;
+ colors = &clearlooks_style->colors;
CHECK_ARGS
SANITIZE_SIZE
gint width,
gint height)
{
+ ClearlooksColors *colors;
+ WidgetParameters params;
+ ArrowParameters arrow;
+ cairo_t *cr;
+ ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
+
(void) shadow;
(void) detail;
(void) fill;
-
- ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
- ClearlooksColors *colors = &clearlooks_style->colors;
- WidgetParameters params;
- ArrowParameters arrow;
- cairo_t *cr = ge_gdk_drawable_to_cairo (window, area);
+
+ cr = ge_gdk_drawable_to_cairo (window, area);
+ colors = &clearlooks_style->colors;
CHECK_ARGS
SANITIZE_SIZE
GtkWidget * widget,
const gchar * detail, gint x, gint y, PangoLayout * layout)
{
- (void) detail;
-
GdkGC *gc;
+ (void) detail;
g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
GtkWidget *widget,
const char *detail)
{
- (void) direction;
- (void) detail;
-
- int width = 1;
- int height = 1;
+ int width;
+ int height;
GdkPixbuf *scaled;
GdkPixbuf *stated;
GdkPixbuf *base_pixbuf;
GdkScreen *screen;
GtkSettings *settings;
-
+
+ width = 1;
+ height = 1;
+
+ (void) direction;
+ (void) detail;
+
/* Oddly, style can be NULL in this function, because
* GtkIconSet can be used without a style and if so
* it uses this function.
OverlapPitchResolution overlap_pitch_resolution() const { return _overlap_pitch_resolution; }
void set_overlap_pitch_resolution(OverlapPitchResolution opr);
- void set_notes (const Sequence<Time>::Notes& n);
+ void set_notes (const typename Sequence<Time>::Notes& n);
typedef boost::shared_ptr< Event<Time> > SysExPtr;
typedef boost::shared_ptr<const Event<Time> > constSysExPtr;
const const_iterator& end() const { return _end_iter; }
+ // CONST iterator implementations (x3)
typename Notes::const_iterator note_lower_bound (Time t) const;
typename PatchChanges::const_iterator patch_change_lower_bound (Time t) const;
typename SysExes::const_iterator sysex_lower_bound (Time t) const;
+ // NON-CONST iterator implementations (x3)
+ typename Notes::iterator note_lower_bound (Time t);
+ typename PatchChanges::iterator patch_change_lower_bound (Time t);
+ typename SysExes::iterator sysex_lower_bound (Time t);
+
bool control_to_midi_event(boost::shared_ptr< Event<Time> >& ev,
const ControlIterator& iter) const;
#include <iostream>
#include <stdint.h>
-#include <stdbool.h>
#include <string>
#include <sys/types.h>
#include <assert.h>
(*iter)->when = when;
(*iter)->value = val;
- if (std::isnan (val)) {
+ if (isnan (val)) {
abort ();
}
#include <climits>
#include <cfloat>
#include <cmath>
+#include <vector>
#include <glibmm/threads.h>
(www.korf.co.uk/spline.pdf) for more details.
*/
- double x[npoints];
- double y[npoints];
+ vector<double> x(npoints);
+ vector<double> y(npoints);
uint32_t i;
ControlList::EventList::const_iterator xx;
template<typename Time>
void
-Sequence<Time>::set_notes (const Sequence<Time>::Notes& n)
+Sequence<Time>::set_notes (const typename Sequence<Time>::Notes& n)
{
_notes = n;
}
+// CONST iterator implementations (x3)
+
/** Return the earliest note with time >= t */
template<typename Time>
typename Sequence<Time>::Notes::const_iterator
return i;
}
+// NON-CONST iterator implementations (x3)
+
+/** Return the earliest note with time >= t */
+template<typename Time>
+typename Sequence<Time>::Notes::iterator
+Sequence<Time>::note_lower_bound (Time t)
+{
+ NotePtr search_note(new Note<Time>(0, t, 0, 0, 0));
+ typename Sequence<Time>::Notes::iterator i = _notes.lower_bound(search_note);
+ assert(i == _notes.end() || (*i)->time() >= t);
+ return i;
+}
+
+/** Return the earliest patch change with time >= t */
+template<typename Time>
+typename Sequence<Time>::PatchChanges::iterator
+Sequence<Time>::patch_change_lower_bound (Time t)
+{
+ PatchChangePtr search (new PatchChange<Time> (t, 0, 0, 0));
+ typename Sequence<Time>::PatchChanges::iterator i = _patch_changes.lower_bound (search);
+ assert (i == _patch_changes.end() || musical_time_greater_or_equal_to ((*i)->time(), t));
+ return i;
+}
+
+/** Return the earliest sysex with time >= t */
+template<typename Time>
+typename Sequence<Time>::SysExes::iterator
+Sequence<Time>::sysex_lower_bound (Time t)
+{
+ SysExPtr search (new Event<Time> (0, t));
+ typename Sequence<Time>::SysExes::iterator i = _sysexes.lower_bound (search);
+ assert (i == _sysexes.end() || (*i)->time() >= t);
+ return i;
+}
+
template<typename Time>
void
Sequence<Time>::get_notes (Notes& n, NoteOperator op, uint8_t val, int chan_mask) const
template class Sequence<Evoral::MusicalTime>;
} // namespace Evoral
-
#include <assert.h>
#include <math.h>
#include <errno.h>
+#ifdef PLATFORM_WINDOWS
+#include <winsock2.h>
+#else
#include <arpa/inet.h>
+#endif
#include "smf.h"
#include "smf_private.h"
{
int cantfail;
- smf_t *smf = malloc(sizeof(smf_t));
+ smf_t *smf = (smf_t*)malloc(sizeof(smf_t));
if (smf == NULL) {
g_critical("Cannot allocate smf_t structure: %s", strerror(errno));
return (NULL);
{
/* Remove all the tracks, from last to first. */
while (smf->tracks_array->len > 0)
- smf_track_delete(g_ptr_array_index(smf->tracks_array, smf->tracks_array->len - 1));
+ smf_track_delete((smf_track_t*)g_ptr_array_index(smf->tracks_array, smf->tracks_array->len - 1));
smf_fini_tempo(smf);
smf_track_t *
smf_track_new(void)
{
- smf_track_t *track = malloc(sizeof(smf_track_t));
+ smf_track_t *track = (smf_track_t*)malloc(sizeof(smf_track_t));
if (track == NULL) {
g_critical("Cannot allocate smf_track_t structure: %s", strerror(errno));
return (NULL);
/* Remove all the events, from last to first. */
while (track->events_array->len > 0)
- smf_event_delete(g_ptr_array_index(track->events_array, track->events_array->len - 1));
+ smf_event_delete((smf_event_t*)g_ptr_array_index(track->events_array, track->events_array->len - 1));
if (track->smf)
smf_track_remove_from_smf(track);
smf_event_t *
smf_event_new(void)
{
- smf_event_t *event = malloc(sizeof(smf_event_t));
+ smf_event_t *event = (smf_event_t*)malloc(sizeof(smf_event_t));
if (event == NULL) {
g_critical("Cannot allocate smf_event_t structure: %s", strerror(errno));
return (NULL);
return (NULL);
event->midi_buffer_length = len;
- event->midi_buffer = malloc(event->midi_buffer_length);
+ event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
if (event->midi_buffer == NULL) {
g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
smf_event_delete(event);
}
event->midi_buffer_length = len;
- event->midi_buffer = malloc(event->midi_buffer_length);
+ event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
if (event->midi_buffer == NULL) {
g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
smf_event_delete(event);
if (event_number > track->number_of_events)
return (NULL);
- event = g_ptr_array_index(track->events_array, event_number - 1);
+ event = (smf_event_t*)g_ptr_array_index(track->events_array, event_number - 1);
assert(event);
#include <assert.h>
#include <math.h>
#include <errno.h>
+#ifdef PLATFORM_WINDOWS
+#include <winsock2.h>
+#else
#include <arpa/inet.h>
+#endif
#include <stdint.h>
#include "smf.h"
#include "smf_private.h"
int off = 0;
char *buf, *extracted;
- buf = malloc(BUFFER_SIZE);
+ buf = (char*)malloc(BUFFER_SIZE);
if (buf == NULL) {
g_critical("smf_event_decode_textual: malloc failed.");
return (NULL);
break;
}
- buf = malloc(BUFFER_SIZE);
+ buf = (char*)malloc(BUFFER_SIZE);
if (buf == NULL) {
g_critical("smf_event_decode_metadata: malloc failed.");
return (NULL);
off += snprintf(buf + off, BUFFER_SIZE - off,
"Time Signature: %d/%d, %d clocks per click, %d notated 32nd notes per quarter note",
- event->midi_buffer[3], (int)pow(2, event->midi_buffer[4]), event->midi_buffer[5],
+ event->midi_buffer[3], (int)pow((double)2, event->midi_buffer[4]), event->midi_buffer[5],
event->midi_buffer[6]);
break;
return (NULL);
}
- buf = malloc(BUFFER_SIZE);
+ buf = (char*)malloc(BUFFER_SIZE);
if (buf == NULL) {
g_critical("smf_event_decode_system_realtime: malloc failed.");
return (NULL);
return (NULL);
}
- buf = malloc(BUFFER_SIZE);
+ buf = (char*)malloc(BUFFER_SIZE);
if (buf == NULL) {
g_critical("smf_event_decode_sysex: malloc failed.");
return (NULL);
if (smf_event_is_sysex(event))
return (smf_event_decode_sysex(event));
- buf = malloc(BUFFER_SIZE);
+ buf = (char*)malloc(BUFFER_SIZE);
if (buf == NULL) {
g_critical("smf_event_decode_system_realtime: malloc failed.");
return (NULL);
return (NULL);
}
- buf = malloc(BUFFER_SIZE);
+ buf = (char*)malloc(BUFFER_SIZE);
if (buf == NULL) {
g_critical("smf_event_decode: malloc failed.");
return (NULL);
int off = 0;
char *buf;
- buf = malloc(BUFFER_SIZE);
+ buf = (char*)malloc(BUFFER_SIZE);
if (buf == NULL) {
g_critical("smf_event_decode: malloc failed.");
return (NULL);
#include <math.h>
#include <errno.h>
#include <ctype.h>
+#ifdef PLATFORM_WINDOWS
+#include <winsock2.h>
+#else
#include <arpa/inet.h>
+#endif
#include "smf.h"
#include "smf_private.h"
return (-1);
}
- tmp_mthd = smf->file_buffer;
+ tmp_mthd = (struct chunk_header_struct*)smf->file_buffer;
if (!chunk_signature_matches(tmp_mthd, "MThd")) {
g_critical("SMF error: MThd signature not found, is that a MIDI file?");
}
event->midi_buffer_length = message_length;
- event->midi_buffer = malloc(event->midi_buffer_length);
+ event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
if (event->midi_buffer == NULL) {
g_critical("Cannot allocate memory in extract_sysex_event(): %s", strerror(errno));
return (-4);
}
event->midi_buffer_length = message_length;
- event->midi_buffer = malloc(event->midi_buffer_length);
+ event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
if (event->midi_buffer == NULL) {
g_critical("Cannot allocate memory in extract_escaped_event(): %s", strerror(errno));
return (-4);
}
event->midi_buffer_length = message_length;
- event->midi_buffer = malloc(event->midi_buffer_length);
+ event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
if (event->midi_buffer == NULL) {
g_critical("Cannot allocate memory in extract_midi_event(): %s", strerror(errno));
return (-4);
len = buffer_length;
}
- str = malloc(len + 1);
+ str = (char*)malloc(len + 1);
if (str == NULL) {
g_critical("Cannot allocate memory in make_string().");
return (NULL);
return (NULL);
}
- smf_extract_vlq((void *)&(event->midi_buffer[2]), event->midi_buffer_length - 2, &string_length, &length_length);
+ smf_extract_vlq((const unsigned char*)(void *)&(event->midi_buffer[2]), event->midi_buffer_length - 2, &string_length, &length_length);
if (string_length <= 0) {
g_critical("smf_event_extract_text: truncated MIDI message.");
return (NULL);
}
- return (make_string((void *)(&event->midi_buffer[2] + length_length), event->midi_buffer_length - 2 - length_length, string_length));
+ return (make_string((const unsigned char*)(void *)(&event->midi_buffer[2] + length_length), event->midi_buffer_length - 2 - length_length, string_length));
}
/**
#include <assert.h>
#include <math.h>
#include <errno.h>
+#ifdef PLATFORM_WINDOWS
+#include <winsock2.h>
+#else
#include <arpa/inet.h>
+#endif
#include "smf.h"
#include "smf_private.h"
smf_extend(smf_t *smf, const int length)
{
int i, previous_file_buffer_length = smf->file_buffer_length;
- char *previous_file_buffer = smf->file_buffer;
+ char *previous_file_buffer = (char*)smf->file_buffer;
/* XXX: Not terribly efficient. */
smf->file_buffer_length += length;
/* "2 +" is for leading 0xFF 0xtype. */
event->midi_buffer_length = 2 + text_length + MAX_VLQ_LENGTH;
- event->midi_buffer = malloc(event->midi_buffer_length);
+ event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
if (event->midi_buffer == NULL) {
g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
smf_event_delete(event);
{
assert(a->event_number == b->event_number);
assert(a->delta_time_pulses == b->delta_time_pulses);
- assert(abs(a->time_pulses - b->time_pulses) <= 2);
+ assert(abs((long)(a->time_pulses - b->time_pulses)) <= 2);
assert(fabs(a->time_seconds - b->time_seconds) <= 0.01);
assert(a->track_number == b->track_number);
assert(a->midi_buffer_length == b->midi_buffer_length);
return (previous_tempo);
}
- tempo = malloc(sizeof(smf_tempo_t));
+ tempo = (smf_tempo_t*)malloc(sizeof(smf_tempo_t));
if (tempo == NULL) {
g_critical("Cannot allocate smf_tempo_t.");
return (NULL);
}
numerator = event->midi_buffer[3];
- denominator = (int)pow(2, event->midi_buffer[4]);
+ denominator = (int)pow((double)2, event->midi_buffer[4]);
clocks_per_click = event->midi_buffer[5];
notes_per_note = event->midi_buffer[6];
if (number >= smf->tempo_array->len)
return (NULL);
- return (g_ptr_array_index(smf->tempo_array, number));
+ return ((smf_tempo_t*)g_ptr_array_index(smf->tempo_array, number));
}
/**
smf_tempo_t *tempo;
while (smf->tempo_array->len > 0) {
- tempo = g_ptr_array_index(smf->tempo_array, smf->tempo_array->len - 1);
+ tempo = (smf_tempo_t*)g_ptr_array_index(smf->tempo_array, smf->tempo_array->len - 1);
assert(tempo);
memset(tempo, 0, sizeof(smf_tempo_t));
#include "SMFTest.hpp"
+#ifdef WIN32
+#include <io.h> // for R_OK
+#endif
+
using namespace std;
CPPUNIT_TEST_SUITE_REGISTRATION( SMFTest );
#include <gtk/gtkuimanager.h>
#include <gtk/gtkactiongroup.h>
+#include <gtkmm.h>
#include <gtkmm/accelmap.h>
#include <gtkmm/uimanager.h>
path++;
}
- char copy[len+1];
- strcpy (copy, path);
- char* slash = strchr (copy, '/');
+ vector<char> copy(len+1);
+ strcpy (©[0], path);
+ char* slash = strchr (©[0], '/');
if (!slash) {
return RefPtr<Action> ();
}
*slash = '\0';
- return get_action (copy, ++slash);
+ return get_action (©[0], ++slash);
}
bool
-BindingProxy::prompter_hiding (GdkEventAny */*ev*/)
+BindingProxy::prompter_hiding (GdkEventAny* /*ev*/)
{
learning_connection.disconnect ();
if (controllable) {
#include <iostream>
+#include <glib/gstdio.h>
+
#include "pbd/xml++.h"
#include "pbd/convert.h"
save (*root);
if (!tree.write (path)) {
- ::unlink (path.c_str());
+ ::g_unlink (path.c_str());
return false;
}
#include "gtkmm2ext/utils.h"
using std::string;
+using std::vector;
using std::map;
using std::max;
using std::cerr;
CairoTextCell::set_size (Cairo::RefPtr<Cairo::Context>& context)
{
const uint32_t lim = (uint32_t) ceil (_width_chars);
- char buf[lim+1];
+ vector<char> buf(lim+1);
uint32_t n;
double max_width = 0.0;
double max_height = 0.0;
buf[n] = '0' + digit;
}
- context->get_text_extents (buf, ext);
+ context->get_text_extents (&buf[0], ext);
max_width = max (ext.width + ext.x_bearing, max_width);
max_height = max (ext.height, max_height);
#include <stdlib.h>
+#include <glibmm.h>
+#include <gdkmm.h>
#include <gdkmm/rectangle.h>
#include <gtkmm2ext/fastmeter.h>
#include <gtkmm2ext/utils.h>
#define UINT_TO_RGB(u,r,g,b) { (*(r)) = ((u)>>16)&0xff; (*(g)) = ((u)>>8)&0xff; (*(b)) = (u)&0xff; }
#define UINT_TO_RGBA(u,r,g,b,a) { UINT_TO_RGB(((u)>>8),r,g,b); (*(a)) = (u)&0xff; }
+
using namespace Gtk;
-using namespace Gdk;
using namespace Glib;
using namespace Gtkmm2ext;
using namespace std;
_stp[2] = stp2;
_stp[3] = stp3;
- set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK);
+ set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
pixrect.x = 1;
pixrect.y = 1;
/* attach our request source to the default main context */
- request_channel.ios()->attach (MainContext::get_default());
+ attach_request_source ();
errors = new TextViewer (800,600);
errors->text().set_editable (false);
}
bool
-UI::just_hide_it (GdkEventAny */*ev*/, Window *win)
+UI::just_hide_it (GdkEventAny* /*ev*/, Window *win)
{
win->hide ();
return true;
}
bool
-UI::color_selection_deleted (GdkEventAny */*ev*/)
+UI::color_selection_deleted (GdkEventAny* /*ev*/)
{
Main::quit ();
return true;
--- /dev/null
+/* GTK+ Integration with platform-specific application-wide features
+ * such as the OS X menubar and application delegate concepts (for X11)
+ *
+ * Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * Copyright (C) 2007 Imendio AB
+ * Copyright (C) 2009 Paul Davis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gtkmm2ext/gtkapplication.h>
+
+int
+gtk_application_init (void)
+{
+ return 0;
+}
+
+void gtk_application_cleanup (void)
+{
+}
+
+void
+gtk_application_set_menu_bar (GtkMenuShell* menushell)
+{
+}
+
+void
+gtk_application_add_app_menu_item (GtkApplicationMenuGroup* group, GtkMenuItem* item)
+{
+}
+
+void
+gtk_application_ready (void)
+{
+}
#ifndef __gtkmm2ext_auto_spin_h__
#define __gtkmm2ext_auto_spin_h__
+#ifdef interface
+#undef interface
+#endif
+
#include <gtkmm.h>
namespace Gtkmm2ext {
#ifndef __gtkmm2ext_click_box_h__
#define __gtkmm2ext_click_box_h__
+#ifdef interface
+#undef interface
+#endif
+
#include <string>
#include <gtkmm.h>
#ifndef __ardour_gtk_doi_h__
#define __ardour_gtk_doi_h__
+#ifdef interface
+#undef interface
+#endif
+
#include <gtkmm.h>
/* XXX g++ 2.95 can't compile this as pair of member function templates */
#include <setjmp.h>
#include <pthread.h>
+#ifdef interface
+#undef interface
+#endif
+
#include <glibmm/thread.h>
#include <gtkmm/widget.h>
#ifndef __qui_popup_h__
#define __qui_popup_h__
+#ifdef interface
+#undef interface
+#endif
+
#include <string>
#include <gtkmm.h>
#ifndef __gtkselector_h__
#define __gtkselector_h__
+#ifdef interface
+#undef interface
+#endif
+
#include <string>
#include <vector>
#ifndef __gtkmm2ext_slider_controller_h__
#define __gtkmm2ext_slider_controller_h__
+#ifdef interface
+#undef interface
+#endif
+
#include <gtkmm.h>
#include <gtkmm2ext/popup.h>
#include <gtkmm2ext/pixfader.h>
#define _BSD_SOURCE
#include <gtkmm2ext/idle_adjustment.h>
#include <gtkmm/main.h>
+#include <glibmm/main.h>
#include <iostream>
+#include "pbd/timersub.h"
+
using namespace Gtk;
using namespace sigc;
using namespace Gtkmm2ext;
#include <unistd.h>
#include <stdio.h> /* for snprintf, grrr */
+#include <glib/gstdio.h>
+
#include <gdk/gdkkeysyms.h>
#include <gtkmm.h>
MotionFeedback::render_pixbuf (int size)
{
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
- char path[32];
+ char *path;
int fd;
+ GError *error = NULL;
- snprintf (path, sizeof (path), "/tmp/mfimg%dXXXXXX", size);
-
- if ((fd = mkstemp (path)) < 0) {
+ fd = g_file_open_tmp ("mfimgXXXXXX", &path, &error);
+ close (fd);
+
+ if(error) {
+ g_critical("failed to open a temporary file for writing: %s.", error->message);
+ g_error_free (error);
return pixbuf;
- }
+ }
GdkColor col2 = {0,0,0,0};
GdkColor col3 = {0,0,0,0};
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);
return pixbuf;
}
}
gint
-PopUp::button_click (GdkEventButton */*ev*/)
+PopUp::button_click (GdkEventButton* /*ev*/)
{
remove ();
return TRUE;
License: LGPLv2+
*/
+#ifdef COMPILER_MSVC
+#include <algorithm>
+using std::min; using std::max;
+#endif
+
#include "gtkmm2ext/prolooks-helpers.h"
static gpointer cairo_color_parent_class = NULL;
(void) collect_flags;
if (collect_values[0].v_pointer) {
CairoColor* object;
- object = collect_values[0].v_pointer;
+ object = (CairoColor*)collect_values[0].v_pointer;
if (object->parent_instance.g_class == NULL) {
return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
static gchar* cairo_value_color_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
CairoColor** object_p;
(void) n_collect_values;
- object_p = collect_values[0].v_pointer;
+ object_p = (CairoColor**)collect_values[0].v_pointer;
if (!object_p) {
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME ((GValue*)value));
}
if (!value->data[0].v_pointer) {
*object_p = NULL;
} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
- *object_p = value->data[0].v_pointer;
+ *object_p = (CairoColor*)value->data[0].v_pointer;
} else {
- *object_p = cairo_color_ref (value->data[0].v_pointer);
+ *object_p = (CairoColor*)cairo_color_ref (value->data[0].v_pointer);
}
return NULL;
}
GParamSpec* cairo_param_spec_color (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
CairoParamSpecColor* spec;
g_return_val_if_fail (g_type_is_a (object_type, CAIRO_TYPE_COLOR), NULL);
- spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
+ spec = (CairoParamSpecColor*)g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
G_PARAM_SPEC (spec)->value_type = object_type;
return G_PARAM_SPEC (spec);
}
void cairo_value_set_color (GValue* value, gpointer v_object) {
CairoColor* old;
g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, CAIRO_TYPE_COLOR));
- old = value->data[0].v_pointer;
+ old = (CairoColor*)value->data[0].v_pointer;
if (v_object) {
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, CAIRO_TYPE_COLOR));
g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
void cairo_value_take_color (GValue* value, gpointer v_object) {
CairoColor* old;
g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, CAIRO_TYPE_COLOR));
- old = value->data[0].v_pointer;
+ old = (CairoColor*)value->data[0].v_pointer;
if (v_object) {
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, CAIRO_TYPE_COLOR));
g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
if (g_once_init_enter (&cairo_color_type_id__volatile)) {
static const GTypeValueTable g_define_type_value_table = { cairo_value_color_init, cairo_value_color_free_value, cairo_value_color_copy_value, cairo_value_color_peek_pointer, "p", cairo_value_color_collect_value, "p", cairo_value_color_lcopy_value };
static const GTypeInfo g_define_type_info = { sizeof (CairoColorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) cairo_color_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CairoColor), 0, (GInstanceInitFunc) cairo_color_instance_init, &g_define_type_value_table };
- static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
+ static const GTypeFundamentalInfo g_define_type_fundamental_info = { (GTypeFundamentalFlags)(G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
GType cairo_color_type_id;
- cairo_color_type_id = g_type_register_fundamental (g_type_fundamental_next (), "CairoColor", &g_define_type_info, &g_define_type_fundamental_info, 0);
+ cairo_color_type_id = g_type_register_fundamental (g_type_fundamental_next (), "CairoColor", &g_define_type_info, &g_define_type_fundamental_info, (GTypeFlags)0);
g_once_init_leave (&cairo_color_type_id__volatile, cairo_color_type_id);
}
return cairo_color_type_id__volatile;
gpointer cairo_color_ref (gpointer instance) {
CairoColor* self;
- self = instance;
+ self = (CairoColor*)instance;
g_atomic_int_inc (&self->ref_count);
return instance;
}
void cairo_color_unref (gpointer instance) {
CairoColor* self;
- self = instance;
+ self = (CairoColor*)instance;
if (g_atomic_int_dec_and_test (&self->ref_count)) {
CAIRO_COLOR_GET_CLASS (self)->finalize (self);
g_type_free_instance ((GTypeInstance *) self);
(void) collect_flags;
if (collect_values[0].v_pointer) {
ProlooksHSL* object;
- object = collect_values[0].v_pointer;
+ object = (ProlooksHSL*)collect_values[0].v_pointer;
if (object->parent_instance.g_class == NULL) {
return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
static gchar* prolooks_value_hsl_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
ProlooksHSL** object_p;
(void) n_collect_values;
- object_p = collect_values[0].v_pointer;
+ object_p = (ProlooksHSL**)collect_values[0].v_pointer;
if (!object_p) {
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME ((GValue*)value));
}
if (!value->data[0].v_pointer) {
*object_p = NULL;
} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
- *object_p = value->data[0].v_pointer;
+ *object_p = (ProlooksHSL*)value->data[0].v_pointer;
} else {
- *object_p = prolooks_hsl_ref (value->data[0].v_pointer);
+ *object_p = (ProlooksHSL*)prolooks_hsl_ref (value->data[0].v_pointer);
}
return NULL;
}
GParamSpec* prolooks_param_spec_hsl (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
ProlooksParamSpecHSL* spec;
g_return_val_if_fail (g_type_is_a (object_type, PROLOOKS_TYPE_HSL), NULL);
- spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
+ spec = (ProlooksParamSpecHSL*)g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
G_PARAM_SPEC (spec)->value_type = object_type;
return G_PARAM_SPEC (spec);
}
void prolooks_value_set_hsl (GValue* value, gpointer v_object) {
ProlooksHSL* old;
g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, PROLOOKS_TYPE_HSL));
- old = value->data[0].v_pointer;
+ old = (ProlooksHSL*)value->data[0].v_pointer;
if (v_object) {
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, PROLOOKS_TYPE_HSL));
g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
void prolooks_value_take_hsl (GValue* value, gpointer v_object) {
ProlooksHSL* old;
g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, PROLOOKS_TYPE_HSL));
- old = value->data[0].v_pointer;
+ old = (ProlooksHSL*)value->data[0].v_pointer;
if (v_object) {
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, PROLOOKS_TYPE_HSL));
g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
if (g_once_init_enter (&prolooks_hsl_type_id__volatile)) {
static const GTypeValueTable g_define_type_value_table = { prolooks_value_hsl_init, prolooks_value_hsl_free_value, prolooks_value_hsl_copy_value, prolooks_value_hsl_peek_pointer, "p", prolooks_value_hsl_collect_value, "p", prolooks_value_hsl_lcopy_value };
static const GTypeInfo g_define_type_info = { sizeof (ProlooksHSLClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) prolooks_hsl_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ProlooksHSL), 0, (GInstanceInitFunc) prolooks_hsl_instance_init, &g_define_type_value_table };
- static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
+ static const GTypeFundamentalInfo g_define_type_fundamental_info = { (GTypeFundamentalFlags)(G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
GType prolooks_hsl_type_id;
- prolooks_hsl_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ProlooksHSL", &g_define_type_info, &g_define_type_fundamental_info, 0);
+ prolooks_hsl_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ProlooksHSL", &g_define_type_info, &g_define_type_fundamental_info, (GTypeFlags)0);
g_once_init_leave (&prolooks_hsl_type_id__volatile, prolooks_hsl_type_id);
}
return prolooks_hsl_type_id__volatile;
gpointer prolooks_hsl_ref (gpointer instance) {
ProlooksHSL* self;
- self = instance;
- g_atomic_int_inc (&self->ref_count);
+ self = (ProlooksHSL*)instance;
+ g_atomic_int_inc (&self->ref_count);
return instance;
}
void prolooks_hsl_unref (gpointer instance) {
ProlooksHSL* self;
- self = instance;
+ self = (ProlooksHSL*)instance;
if (g_atomic_int_dec_and_test (&self->ref_count)) {
PROLOOKS_HSL_GET_CLASS (self)->finalize (self);
g_type_free_instance ((GTypeInstance *) self);
(void) n_collect_values;
if (collect_values[0].v_pointer) {
ProlooksHSV* object;
- object = collect_values[0].v_pointer;
+ object = (ProlooksHSV*)collect_values[0].v_pointer;
if (object->parent_instance.g_class == NULL) {
return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
static gchar* prolooks_value_hsv_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
ProlooksHSV** object_p;
(void) n_collect_values;
- object_p = collect_values[0].v_pointer;
+ object_p = (ProlooksHSV**)collect_values[0].v_pointer;
if (!object_p) {
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME ((GValue*)value));
}
if (!value->data[0].v_pointer) {
*object_p = NULL;
} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
- *object_p = value->data[0].v_pointer;
+ *object_p = (ProlooksHSV*)value->data[0].v_pointer;
} else {
- *object_p = prolooks_hsv_ref (value->data[0].v_pointer);
+ *object_p = (ProlooksHSV*)prolooks_hsv_ref (value->data[0].v_pointer);
}
return NULL;
}
GParamSpec* prolooks_param_spec_hsv (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
ProlooksParamSpecHSV* spec;
g_return_val_if_fail (g_type_is_a (object_type, PROLOOKS_TYPE_HSV), NULL);
- spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
+ spec = (ProlooksParamSpecHSV*)g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
G_PARAM_SPEC (spec)->value_type = object_type;
return G_PARAM_SPEC (spec);
}
void prolooks_value_set_hsv (GValue* value, gpointer v_object) {
ProlooksHSV* old;
g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, PROLOOKS_TYPE_HSV));
- old = value->data[0].v_pointer;
+ old = (ProlooksHSV*)value->data[0].v_pointer;
if (v_object) {
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, PROLOOKS_TYPE_HSV));
g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
void prolooks_value_take_hsv (GValue* value, gpointer v_object) {
ProlooksHSV* old;
g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, PROLOOKS_TYPE_HSV));
- old = value->data[0].v_pointer;
+ old = (ProlooksHSV*)value->data[0].v_pointer;
if (v_object) {
g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, PROLOOKS_TYPE_HSV));
g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
if (g_once_init_enter (&prolooks_hsv_type_id__volatile)) {
static const GTypeValueTable g_define_type_value_table = { prolooks_value_hsv_init, prolooks_value_hsv_free_value, prolooks_value_hsv_copy_value, prolooks_value_hsv_peek_pointer, "p", prolooks_value_hsv_collect_value, "p", prolooks_value_hsv_lcopy_value };
static const GTypeInfo g_define_type_info = { sizeof (ProlooksHSVClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) prolooks_hsv_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ProlooksHSV), 0, (GInstanceInitFunc) prolooks_hsv_instance_init, &g_define_type_value_table };
- static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
+ static const GTypeFundamentalInfo g_define_type_fundamental_info = { (GTypeFundamentalFlags)(G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
GType prolooks_hsv_type_id;
- prolooks_hsv_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ProlooksHSV", &g_define_type_info, &g_define_type_fundamental_info, 0);
+ prolooks_hsv_type_id = g_type_register_fundamental (g_type_fundamental_next (), "ProlooksHSV", &g_define_type_info, &g_define_type_fundamental_info, (GTypeFlags)0);
g_once_init_leave (&prolooks_hsv_type_id__volatile, prolooks_hsv_type_id);
}
return prolooks_hsv_type_id__volatile;
gpointer prolooks_hsv_ref (gpointer instance) {
ProlooksHSV* self;
- self = instance;
+ self = (ProlooksHSV*)instance;
g_atomic_int_inc (&self->ref_count);
return instance;
}
void prolooks_hsv_unref (gpointer instance) {
ProlooksHSV* self;
- self = instance;
+ self = (ProlooksHSV*)instance;
if (g_atomic_int_dec_and_test (&self->ref_count)) {
PROLOOKS_HSV_GET_CLASS (self)->finalize (self);
g_type_free_instance ((GTypeInstance *) self);
#include <vector>
#include <string>
+#include <glibmm.h>
+#include <gdkmm.h>
+
#include "pbd/pathscanner.h"
#include "gtkmm2ext/keyboard.h"
using namespace MIDI;
-Channel::Channel (byte channelnum, Port &p)
+Channel::Channel (MIDI::byte channelnum, Port &p)
: _port (p)
{
_channel_number = channelnum;
}
void
-Channel::process_program_change (Parser & /*parser*/, byte val)
+Channel::process_program_change (Parser & /*parser*/, MIDI::byte val)
{
_program_number = val;
}
void
-Channel::process_chanpress (Parser & /*parser*/, byte val)
+Channel::process_chanpress (Parser & /*parser*/, MIDI::byte val)
{
_chanpress = val;
}
* \return true if success
*/
bool
-Channel::channel_msg (byte id, byte val1, byte val2, timestamp_t timestamp)
+Channel::channel_msg (MIDI::byte id, MIDI::byte val1, MIDI::byte val2, timestamp_t timestamp)
{
unsigned char msg[3];
int len = 0;
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#ifdef COMPILER_MSVC
+#undef O_NONBLOCK
+#define O_NONBLOCK 0
+#endif
+#if defined(PLATFORM_WINDOWS)
+#include <winsock2.h>
+#else
#include <netdb.h>
+#endif
-#if defined(WIN32)
+#if defined(PLATFORM_WINDOWS)
static WSADATA g_wsaData;
typedef int socklen_t;
#else
{
// Get interface address from supplied name.
-#if !defined(WIN32)
+#if !defined(PLATFORM_WINDOWS)
struct ifreq ifr;
::strncpy(ifr.ifr_name, ifname.c_str(), sizeof(ifr.ifr_name));
return false;
-#endif // !WIN32
+#endif // !PLATFORM_WINDOWS'
}
bool
IPMIDIPort::open_sockets (int base_port, const string& ifname)
{
+#if !defined(PLATFORM_WINDOWS)
int protonum = 0;
struct protoent *proto = ::getprotobyname("IP");
}
return true;
+#else
+ return false;
+#endif // !PLATFORM_WINDOWS'
}
int
-IPMIDIPort::write (const byte* msg, size_t msglen, timestamp_t /* ignored */) {
+IPMIDIPort::write (const MIDI::byte* msg, size_t msglen, timestamp_t /* ignored */) {
if (sockout) {
Glib::Threads::Mutex::Lock lm (write_lock);
}
int
-IPMIDIPort::read (byte* /*buf*/, size_t /*bufsize*/)
+IPMIDIPort::read (MIDI::byte* /*buf*/, size_t /*bufsize*/)
{
/* nothing to do here - all handled by parse() */
return 0;
#include <string>
#include <iostream>
-#if defined(WIN32)
+#if defined(PLATFORM_WINDOWS)
#include <winsock.h>
#elif defined(__FREE_BSD__)
#include <netinet/in.h>
* now due to use of JackPortIsXXXX
*/
+#include <pthread.h>
+
#include "pbd/xml++.h"
+#ifndef PLATFORM_WINDOWS
#include "pbd/crossthread.h"
+#endif
#include "pbd/signals.h"
#include "pbd/ringbuffer.h"
<< "List size " << cns._patch_list.size() << endl
<< "Patch list name = [" << cns._patch_list_name << ']' << endl
<< "Available channels : ";
- for (set<uint8_t>::iterator x = cns._available_for_channels.begin(); x != cns._available_for_channels.end(); ++x) {
+ for (set<uint8_t>::const_iterator x = cns._available_for_channels.begin(); x != cns._available_for_channels.end(); ++x) {
os << (int) (*x) << ' ';
}
os << endl;
#include "midi++/port.h"
#include "midi++/parser.h"
+#ifndef __INT_MAX__ // 'ssize_t' won't be defined yet
+typedef long ssize_t;
+#endif
+
using namespace std;
using namespace MIDI;
using namespace PBD;
}
void
-MachineControl::set_receive_device_id (byte id)
+MachineControl::set_receive_device_id (MIDI::byte id)
{
_receive_device_id = id & 0x7f;
}
void
-MachineControl::set_send_device_id (byte id)
+MachineControl::set_send_device_id (MIDI::byte id)
{
_send_device_id = id & 0x7f;
}
bool
-MachineControl::is_mmc (byte *sysex_buf, size_t len)
+MachineControl::is_mmc (MIDI::byte *sysex_buf, size_t len)
{
if (len < 4 || len > 48) {
return false;
}
void
-MachineControl::process_mmc_message (Parser &, byte *msg, size_t len)
+MachineControl::process_mmc_message (Parser &, MIDI::byte *msg, size_t len)
{
size_t skiplen;
byte *mmc_msg;
}
int
-MachineControl::do_masked_write (byte *msg, size_t len)
+MachineControl::do_masked_write (MIDI::byte *msg, size_t len)
{
/* return the number of bytes "consumed" */
}
void
-MachineControl::write_track_status (byte *msg, size_t /*len*/, byte reg)
+MachineControl::write_track_status (MIDI::byte *msg, size_t /*len*/, MIDI::byte reg)
{
size_t n;
ssize_t base_track;
}
int
-MachineControl::do_locate (byte *msg, size_t /*msglen*/)
+MachineControl::do_locate (MIDI::byte *msg, size_t /*msglen*/)
{
if (msg[2] == 0) {
warning << "MIDI::MMC: locate [I/F] command not supported"
}
int
-MachineControl::do_step (byte *msg, size_t /*msglen*/)
+MachineControl::do_step (MIDI::byte *msg, size_t /*msglen*/)
{
int steps = msg[2] & 0x3f;
}
int
-MachineControl::do_shuttle (byte *msg, size_t /*msglen*/)
+MachineControl::do_shuttle (MIDI::byte *msg, size_t /*msglen*/)
{
size_t forward;
byte sh = msg[2];
#undef DEBUG_MTC
bool
-Parser::possible_mtc (byte *sysex_buf, size_t msglen)
+Parser::possible_mtc (MIDI::byte *sysex_buf, size_t msglen)
{
byte fake_mtc_time[5];
}
void
-Parser::process_mtc_quarter_frame (byte *msg)
+Parser::process_mtc_quarter_frame (MIDI::byte *msg)
{
int which_quarter_frame = (msg[1] & 0xf0) >> 4;
}
void
-Parser::trace_event (Parser &, byte *msg, size_t len)
+Parser::trace_event (Parser &, MIDI::byte *msg, size_t len)
{
eventType type;
ostream *o;
}
void
-Parser::signal (byte *msg, size_t len)
+Parser::signal (MIDI::byte *msg, size_t len)
{
channel_t chan = msg[0]&0xF;
int chan_i = chan;
}
bool
-Parser::possible_mmc (byte *msg, size_t msglen)
+Parser::possible_mmc (MIDI::byte *msg, size_t msglen)
{
if (!MachineControl::is_mmc (msg, msglen)) {
return false;
#include "ardour/buffer_set.h"
#include "ardour/audio_buffer.h"
#include "ardour/pannable.h"
+#include "ardour/visibility.h"
#include "i18n.h"
#include "panner_1in2out.h"
Panner1in2out::factory
};
-extern "C" { PanPluginDescriptor* panner_descriptor () { return &_descriptor; } }
+extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; }
Panner1in2out::Panner1in2out (boost::shared_ptr<Pannable> p)
: Panner (p)
#include "ardour/types.h"
#include "ardour/panner.h"
+
namespace ARDOUR {
class Panner1in2out : public Panner
Panner1in2out (boost::shared_ptr<Pannable>);
~Panner1in2out ();
- void set_position (double);
- bool clamp_position (double&);
+ void set_position (double);
+ bool clamp_position (double&);
std::pair<double, double> position_range () const;
double position() const;
obj.source = [ 'panner_1in2out.cc' ]
obj.export_includes = ['.']
obj.cxxflags = '-DPACKAGE="libardour_pan1in2out"'
+ obj.defines = [ 'ARDOURPANNER_DLL_EXPORTS' ]
obj.includes = ['.']
obj.name = 'libardour_pan1in2out'
obj.target = 'pan1in2out'
#include "ardour/runtime_functions.h"
#include "ardour/session.h"
#include "ardour/utils.h"
+#include "ardour/visibility.h"
#include "ardour/mix.h"
#include "panner_2in2out.h"
Panner2in2out::factory
};
-extern "C" { PanPluginDescriptor* panner_descriptor () { return &_descriptor; } }
+extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; }
Panner2in2out::Panner2in2out (boost::shared_ptr<Pannable> p)
: Panner (p)
obj.source = [ 'panner_2in2out.cc' ]
obj.export_includes = ['.']
obj.cxxflags = '-DPACKAGE="libardour_pan2in2out"'
+ obj.defines = [ 'ARDOURPANNER_DLL_EXPORTS' ]
obj.includes = ['.']
obj.name = 'libardour_pan2in2out'
obj.target = 'pan2in2out'
#include <iostream>
#include <string>
+#ifdef COMPILER_MSVC
+#include <malloc.h>
+#endif
+
#include "pbd/cartesian.h"
#include "pbd/compose.h"
VBAPanner::factory
};
-extern "C" { PanPluginDescriptor* panner_descriptor () { return &_descriptor; } }
+extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; }
VBAPanner::Signal::Signal (Session&, VBAPanner&, uint32_t, uint32_t n_speakers)
{
}
void
-VBAPanner::Signal::Signal::resize_gains (uint32_t n)
+VBAPanner::Signal::resize_gains (uint32_t n)
{
gains.assign (n, 0.0);
}
assert (sz == obufs.count().n_audio());
- int8_t outputs[sz]; // on the stack, no malloc
+ int8_t *outputs = (int8_t*)alloca(sz); // on the stack, no malloc
/* set initial state of each output "record"
*/
/* at this point, we can test a speaker's status:
- (outputs[o] & 1) <= in use before
- (outputs[o] & 2) <= in use this time
- (outputs[o] & 3) == 3 <= in use both times
- outputs[o] == 0 <= not in use either time
+ (*outputs[o] & 1) <= in use before
+ (*outputs[o] & 2) <= in use this time
+ (*outputs[o] & 3) == 3 <= in use both times
+ *outputs[o] == 0 <= not in use either time
*/
of the software.
*/
+#ifdef COMPILER_MSVC
+#pragma warning ( disable : 4244 )
+#endif
+
+#include <vector>
#include <cmath>
#include <algorithm>
#include <stdlib.h>
const double VBAPSpeakers::MIN_VOL_P_SIDE_LGTH = 0.01;
+typedef std::vector<double> DoubleVector;
+typedef std::vector<float> FloatVector;
+typedef std::vector<bool> BoolVector;
+typedef std::vector<int> IntVector;
+typedef std::vector<IntVector> IntVector2D;
+typedef std::vector<DoubleVector> DoubleVector2D;
+
VBAPSpeakers::VBAPSpeakers (boost::shared_ptr<Speakers> s)
: _dimension (2)
, _parent (s)
int i,j,k,l,table_size;
int n_speakers = _speakers.size ();
- int connections[n_speakers][n_speakers];
- float distance_table[((n_speakers * (n_speakers - 1)) / 2)];
- int distance_table_i[((n_speakers * (n_speakers - 1)) / 2)];
- int distance_table_j[((n_speakers * (n_speakers - 1)) / 2)];
- float distance;
- struct ls_triplet_chain *trip_ptr, *prev, *tmp_ptr;
- if (n_speakers == 0) {
+ if (n_speakers < 1) {
return;
}
+ FloatVector distance_table(((n_speakers * (n_speakers - 1)) / 2));
+ IntVector distance_table_i(((n_speakers * (n_speakers - 1)) / 2));
+ IntVector distance_table_j(((n_speakers * (n_speakers - 1)) / 2));
+ IntVector2D connections(n_speakers, IntVector(n_speakers));
+ float distance;
+ struct ls_triplet_chain *trip_ptr, *prev, *tmp_ptr;
+
for (i = 0; i < n_speakers; i++) {
for (j = i+1; j < n_speakers; j++) {
for(k=j+1;k<n_speakers;k++) {
matrices and stores the data to a global array
*/
const int n_speakers = _speakers.size();
- const double AZIMUTH_DELTA_THRESHOLD_DEGREES = (180.0/M_PI) * (M_PI - 0.175);
- int sorted_speakers[n_speakers];
- bool exists[n_speakers];
- double inverse_matrix[n_speakers][4];
- int expected_pairs = 0;
- int pair;
- int speaker;
-
- if (n_speakers == 0) {
+ if (n_speakers < 1) {
return;
}
+ IntVector sorted_speakers(n_speakers);
+ BoolVector exists(n_speakers);
+ DoubleVector2D inverse_matrix(n_speakers, DoubleVector(4));
+ const double AZIMUTH_DELTA_THRESHOLD_DEGREES = (180.0/M_PI) * (M_PI - 0.175);
+ int expected_pairs = 0;
+ int pair;
+ int speaker;
+
for (speaker = 0; speaker < n_speakers; ++speaker) {
exists[speaker] = false;
}
/* sort loudspeakers according their aximuth angle */
- sort_2D_lss (sorted_speakers);
+ sort_2D_lss (&sorted_speakers[0]);
/* adjacent loudspeakers are the loudspeaker pairs to be used.*/
for (speaker = 0; speaker < n_speakers-1; speaker++) {
_speakers[sorted_speakers[speaker]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) {
if (calc_2D_inv_tmatrix( _speakers[sorted_speakers[speaker]].angles().azi,
_speakers[sorted_speakers[speaker+1]].angles().azi,
- inverse_matrix[speaker]) != 0){
+ &inverse_matrix[speaker][0]) != 0){
exists[speaker] = true;
expected_pairs++;
}
+_speakers[sorted_speakers[0]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) {
if (calc_2D_inv_tmatrix(_speakers[sorted_speakers[n_speakers-1]].angles().azi,
_speakers[sorted_speakers[0]].angles().azi,
- inverse_matrix[n_speakers-1]) != 0) {
+ &inverse_matrix[n_speakers-1][0]) != 0) {
exists[n_speakers-1] = true;
expected_pairs++;
}
obj.source = [ 'vbap_speakers.cc', 'vbap.cc' ]
obj.export_includes = ['.']
obj.cxxflags = '-DPACKAGE="libardour_panvbap"'
+ obj.defines = [ 'ARDOURPANNER_DLL_EXPORTS' ]
obj.includes = ['.']
obj.name = 'libardour_panvbap'
obj.target = 'panvbap'
#include <cstring>
#include <stdint.h>
+#ifdef COMPILER_MSVC
+#include <io.h> // Microsoft's nearest equivalent to <unistd.h>
+#else
#include <unistd.h>
+#endif
#include <fcntl.h>
#include <cerrno>
#include <cstring>
#include "i18n.h"
+#include "pbd/debug.h"
+
using namespace std;
using namespace PBD;
using namespace Glib;
BaseUI::RequestType BaseUI::Quit = BaseUI::new_request_type();
BaseUI::BaseUI (const string& str)
- : request_channel (true)
+ : m_context(MainContext::get_default())
, run_loop_thread (0)
, _name (str)
+#ifndef PLATFORM_WINDOWS
+ , request_channel (true)
+#endif
{
base_ui_instance = this;
+#ifndef PLATFORM_WINDOWS
request_channel.ios()->connect (sigc::mem_fun (*this, &BaseUI::request_handler));
+#endif
/* derived class must set _ok */
}
void
BaseUI::main_thread ()
{
- DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: event loop running in thread %2\n", name(), pthread_self()));
+ DEBUG_TRACE (DEBUG::EventLoop, string_compose ("%1: event loop running in thread %2\n", name(), pthread_name()));
set_event_loop_for_thread (this);
thread_init ();
_main_loop->get_context()->signal_idle().connect (sigc::mem_fun (*this, &BaseUI::signal_running));
/* to be called by UI's that need/want their own distinct, self-created event loop thread.
*/
- _main_loop = MainLoop::create (MainContext::create());
- request_channel.ios()->attach (_main_loop->get_context());
-
- /* glibmm hack - drop the refptr to the IOSource now before it can hurt */
- request_channel.drop_ios ();
+ m_context = MainContext::create();
+ _main_loop = MainLoop::create (m_context);
+ attach_request_source ();
Glib::Threads::Mutex::Lock lm (_run_lock);
run_loop_thread = Glib::Threads::Thread::create (mem_fun (*this, &BaseUI::main_thread));
}
}
+#ifdef PLATFORM_WINDOWS
+gboolean
+BaseUI::_request_handler (gpointer data)
+{
+ BaseUI* ui = static_cast<BaseUI*>(data);
+ return ui->request_handler ();
+}
+
+bool
+BaseUI::request_handler ()
+{
+ DEBUG_TRACE (DEBUG::EventLoop, "BaseUI::request_handler\n");
+ handle_ui_requests ();
+ // keep calling indefinitely at the timeout interval
+ return true;
+}
+
+#else
bool
BaseUI::request_handler (Glib::IOCondition ioc)
{
/* handle requests */
+ DEBUG_TRACE (DEBUG::EventLoop, "BaseUI::request_handler\n");
handle_ui_requests ();
}
return true;
}
-
+#endif
+
+void
+BaseUI::signal_new_request ()
+{
+ DEBUG_TRACE (DEBUG::EventLoop, "BaseUI::signal_new_request\n");
+#ifdef PLATFORM_WINDOWS
+ // handled in timeout, how to signal...?
+#else
+ request_channel.wakeup ();
+#endif
+}
+
+/**
+ * This method relies on the caller having already set m_context
+ */
+void
+BaseUI::attach_request_source ()
+{
+ DEBUG_TRACE (DEBUG::EventLoop, "BaseUI::attach_request_source\n");
+#ifdef PLATFORM_WINDOWS
+ GSource* request_source = g_timeout_source_new(200);
+ g_source_set_callback (request_source, &BaseUI::_request_handler, this, NULL);
+ g_source_attach (request_source, m_context->gobj());
+#else
+ request_channel.ios()->attach (m_context);
+ /* glibmm hack - drop the refptr to the IOSource now before it can hurt */
+ request_channel.drop_ios ();
+#endif
+}
*/
-#include <string>
+#ifdef COMPILER_MSVC
+#include <io.h> // Microsoft's nearest equivalent to <unistd.h>
+using PBD::readdir;
+using PBD::opendir;
+using PBD::closedir;
+#else
#include <dirent.h>
#include <unistd.h>
+#endif
+
+#include <string>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
+#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include "pbd/error.h"
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;
#include <vector>
#include <algorithm>
+#include <boost/tokenizer.hpp>
+
#include "pbd/debug.h"
#include "i18n.h"
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;
int
PBD::parse_debug_options (const char* str)
{
- char* p;
- char* sp;
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep (",");
+ tokenizer tokens (string(str), sep);
uint64_t bits = 0;
- char* copy = strdup (str);
-
- p = strtok_r (copy, ",", &sp);
- while (p) {
- if (strcasecmp (p, "list") == 0) {
+ for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
+ if (*tok_iter == "list") {
list_debug_options ();
- free (copy);
return 1;
}
- if (strcasecmp (p, "all") == 0) {
+ if (*tok_iter == "all") {
PBD::set_debug_bits (~0ULL);
- free (copy);
return 0;
}
for (map<const char*,uint64_t>::iterator i = _debug_bit_map().begin(); i != _debug_bit_map().end(); ++i) {
- if (strncasecmp (p, i->first, strlen (p)) == 0) {
+ const char* cstr = (*tok_iter).c_str();
+
+ if (strncasecmp (cstr, i->first, strlen (cstr)) == 0) {
bits |= i->second;
}
}
-
- p = strtok_r (0, ",", &sp);
}
- free (copy);
PBD::set_debug_bits (bits);
return 0;
}
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
-#include <pthread.h>
#include <stdlib.h>
+#include "pbd/pthread_utils.h"
+
int (*pbd_alloc_allowed) () = 0;
/** Thread-local key whose value is set to 1 if malloc checking is disabled
*/
+#include <glib.h>
+
#include <cstdlib>
#include "pbd/epa.h"
#include "pbd/strsplit.h"
+#ifdef COMPILER_MSVC
+#define environ _environ
+_CRTIMP extern char ** _environ;
+#else
extern char** environ;
+#endif
using namespace PBD;
using namespace std;
/* fetch environment from named environment variable, rather than "environ"
*/
- const char* estr = getenv (_envname.c_str());
+ const char* estr = g_getenv (_envname.c_str());
if (!estr) {
return;
clear ();
for (map<string,string>::const_iterator i = e.begin(); i != e.end(); ++i) {
- setenv (i->first.c_str(), i->second.c_str(), 1);
+ g_setenv (i->first.c_str(), i->second.c_str(), 1);
}
}
}
string before = estring.substr (0, equal);
- unsetenv(before.c_str());
+ g_unsetenv(before.c_str());
}
}
--- /dev/null
+/*
+ Copyright (C) 2008 John Emmas
+
+ 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 <pbd/fallback_folders.h>
+#include <glib.h>
+#include <glibmm.h>
+#include <string.h>
+
+
+
+#ifdef PLATFORM_WINDOWS // Would not be relevant for Cygwin!!
+#include <shlobj.h>
+#include <winreg.h>
+
+//***************************************************************
+//
+// get_win_special_folder()
+//
+// Gets the full path name that corresponds of one of the Windows
+// special folders, such as "My Documents" and the like. The input
+// parameter must be one of the corresponding CSIDL values, such
+// as CSIDL_SYSTEM etc.
+//
+// Returns:
+//
+// On Success: A pointer to a newly allocated string containing
+// the name of the special folder (must later be freed).
+// On Failure: NULL
+//
+gchar *
+get_win_special_folder (int csidl)
+{
+wchar_t path[PATH_MAX+1];
+HRESULT hr;
+LPITEMIDLIST pidl = 0;
+gchar *retval = 0;
+
+ if (S_OK == (hr = SHGetSpecialFolderLocation (0, csidl, &pidl)))
+ {
+ if (SHGetPathFromIDListW (pidl, path))
+ retval = g_utf16_to_utf8 ((const gunichar2*)path, -1, 0, 0, 0);
+ CoTaskMemFree (pidl);
+ }
+
+ return retval;
+}
+#endif // PLATFORM_WINDOWS
+
+namespace PBD {
+
+static gchar **fallback_folders = 0;
+
+//***************************************************************
+//
+// get_platform_fallback_folders()
+//
+// Returns an array of folders to fall back to if the folders
+// weren't named at build time and subsequently couldn't be found
+// in the user's environment. This might not be needed any more
+// because the function 'fixup_bundle_environment()' (in the
+// gtk2_ardour branch) now explicitly sets up any environment
+// paths that the program will need at run time. However, having
+// the folders here might help us to simplify the above function
+// which would be useful (currently, there are different versions
+// of 'fixup_bundle_environment()' for each supported platform).
+// Twelve fallback folders are currently catered for, corresponding to:-
+//
+// LOCALEDIR
+// GTK_DIR
+// CONFIG_DIR
+// ARDOUR_DIR
+// MODULE_DIR
+// DATA_DIR
+// ICONS_DIR
+// PIXMAPS_DIR
+// CONTROL_SURFACES_DIR
+// VAMP_DIR
+// LADSPA_PATH - note that there's only one entry in the path
+// VST_PATH - note that there may only be one entry in the path
+//
+// Returns:
+//
+// On Success: A pointer to an array containing the above dirs.
+// On Failure: NULL
+//
+#ifdef PLATFORM_WINDOWS // Would not be relevant for Cygwin!!
+
+static gchar**
+get_platform_fallback_folders ()
+{
+gchar **fallback_dir_vector = 0;
+const gchar *pUsrHome = 0; // Do not free !!
+
+ if (!fallback_folders)
+ {
+ GArray *pFallbackDirs;
+ gchar *pAppData = 0;
+ gchar *pMyAppData = 0;
+ gchar *pExeRoot = 0;
+ gchar *pPersonal = 0;
+
+ pFallbackDirs = g_array_new (TRUE, TRUE, sizeof (char *));
+
+ if (pFallbackDirs)
+ {
+ /* Get the path for the user's personal folder */
+ gchar *pPersonalTemp = get_win_special_folder (CSIDL_PERSONAL);
+
+ /* and the path for the user's personal application data */
+ gchar *pMyAppDataTemp = get_win_special_folder (CSIDL_LOCAL_APPDATA);
+
+ /* and the path for common application data ("Documents and Settings\All Users\Application Data") */
+ gchar *pAppDataTemp = get_win_special_folder (CSIDL_COMMON_APPDATA);
+
+ if (0 == pAppDataTemp)
+ pAppData = g_build_filename("C:\\", "Documents and Settings", "All Users", "Application Data", PROGRAM_NAME, "local", 0);
+ else
+ {
+ pAppData = g_build_filename(pAppDataTemp, PROGRAM_NAME, "local", 0);
+ g_free (pAppDataTemp);
+ }
+
+ if (0 == pMyAppDataTemp)
+ {
+ pMyAppData = g_build_filename(g_get_home_dir(), "Application Data", "local", 0);
+ }
+ else
+ {
+ pMyAppData = g_build_filename(pMyAppDataTemp, 0);
+ g_free (pMyAppDataTemp);
+ }
+
+ if (0 == pPersonalTemp)
+ pPersonal = g_build_filename(g_get_home_dir(), 0);
+ else
+ {
+ pPersonal = g_build_filename(pPersonalTemp, 0);
+ g_free (pPersonalTemp);
+ }
+
+ /* Get the path to the running application */
+ pExeRoot = g_win32_get_package_installation_directory_of_module (0);
+
+ if (0 == pExeRoot)
+ {
+ pExeRoot = g_build_filename("C:\\", "Program Files", PROGRAM_NAME, 0);
+ }
+
+ if ((pExeRoot) && (pAppData) && (pMyAppData) && (pPersonal))
+ {
+ gchar tmp[PATH_MAX+1];
+ gchar* p;
+
+ // Build our LOCALEDIR entry
+ if (0 != (p = g_build_filename(pAppData, "share", "locale", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our GTK_DIR entry
+ if (0 != (p = g_build_filename(pPersonal, ".gtk-2.0", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our CONFIG_DIR entry
+ if (0 != (p = g_build_filename(pAppData, "etc", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our ARDOUR_DIR entry
+ p = g_build_filename(pMyAppData, PROGRAM_NAME, 0);
+
+ if (0 != p)
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our MODULE_DIR entry
+ strcpy(tmp, pExeRoot);
+ if (0 != (p = strrchr (tmp, G_DIR_SEPARATOR)))
+ {
+ *p = '\0';
+
+ if (0 != (p = g_build_filename(tmp, 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our DATA_DIR entry
+ if (0 != (p = g_build_filename(pAppData, "share", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our ICONS_DIR entry
+ if (0 != (p = g_build_filename(pAppData, "share", "icons", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our PIXMAPS_DIR entry
+ if (0 != (p = g_build_filename(pAppData, "share", "pixmaps", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our CONTROL_SURFACES_DIR entry
+ if (0 != (p = g_build_filename(pExeRoot, "bin", "surfaces", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our VAMP_DIR entry
+ p = g_build_filename(pExeRoot, "bin", "vamp", 0);
+ if (p)
+ g_array_append_val (pFallbackDirs, p);
+ else
+ g_array_append_val (pFallbackDirs, "");
+
+ // Next, build our LADSPA_PATH entry
+ p = g_build_filename(pExeRoot, "bin", "plugins", 0);
+ if (p)
+ g_array_append_val (pFallbackDirs, p);
+ else
+ g_array_append_val (pFallbackDirs, "");
+
+ // And finally, build our VST_PATH entry
+ DWORD dwType = REG_SZ; HKEY hKey;
+ DWORD dwSize = PATH_MAX; p = 0;
+ if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_CURRENT_USER, "Software\\VST", 0, KEY_READ, &hKey))
+ {
+ // Look for the user's VST Registry entry
+ if (ERROR_SUCCESS == RegQueryValueExA (hKey, "VSTPluginsPath", 0, &dwType, (LPBYTE)tmp, &dwSize))
+ p = g_build_filename (Glib::locale_to_utf8(tmp).c_str(), 0);
+
+ RegCloseKey (hKey);
+ }
+
+ if (p == 0)
+ if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_LOCAL_MACHINE, "Software\\VST", 0, KEY_READ, &hKey))
+ {
+ // Look for a global VST Registry entry
+ if (ERROR_SUCCESS == RegQueryValueExA (hKey, "VSTPluginsPath", 0, &dwType, (LPBYTE)tmp, &dwSize))
+ p = g_build_filename (Glib::locale_to_utf8(tmp).c_str(), 0);
+
+ RegCloseKey (hKey);
+ }
+
+ if (p == 0)
+ {
+ gchar *pVSTx86 = 0;
+ gchar *pProgFilesX86 = get_win_special_folder (CSIDL_PROGRAM_FILESX86);
+
+ if (pProgFilesX86)
+ {
+ // Look for a VST folder under C:\Program Files (x86)
+ if (pVSTx86 = g_build_filename (pProgFilesX86, "Steinberg", "VSTPlugins", 0))
+ {
+ if (Glib::file_test (pVSTx86, Glib::FILE_TEST_EXISTS))
+ if (Glib::file_test (pVSTx86, Glib::FILE_TEST_IS_DIR))
+ p = g_build_filename (pVSTx86, 0);
+
+ g_free (pVSTx86);
+ }
+
+ g_free (pProgFilesX86);
+ }
+
+ if (p == 0)
+ {
+ // Look for a VST folder under C:\Program Files
+ gchar *pVST = 0;
+ gchar *pProgFiles = get_win_special_folder (CSIDL_PROGRAM_FILES);
+
+ if (pProgFiles)
+ {
+ if (pVST = g_build_filename (pProgFiles, "Steinberg", "VSTPlugins", 0))
+ {
+ if (Glib::file_test (pVST, Glib::FILE_TEST_EXISTS))
+ if (Glib::file_test (pVST, Glib::FILE_TEST_IS_DIR))
+ p = g_build_filename (pVST, 0);
+
+ g_free (pVST);
+ }
+
+ g_free (pProgFiles);
+ }
+ }
+ }
+
+ if (p == 0)
+ {
+ // If all else failed, assume the plugins are under "My Documents"
+ pUsrHome = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
+ if (pUsrHome)
+ p = g_build_filename (pUsrHome, "Plugins", "VST", 0);
+ else
+ {
+ pUsrHome = g_build_filename(g_get_home_dir(), "My Documents", 0);
+ if (pUsrHome)
+ p = g_build_filename (pUsrHome, "Plugins", "VST", 0);
+ }
+ }
+ else
+ {
+ gchar* q = 0;
+
+ // Concatenate the registry path with the user's personal path
+ pUsrHome = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
+
+ if (pUsrHome)
+ {
+ q = p;
+ p = g_build_path (";", q, g_build_filename(pUsrHome, "Plugins", "VST", 0), 0);
+ }
+ else
+ {
+ pUsrHome = g_build_filename(g_get_home_dir(), "My Documents", 0);
+ if (pUsrHome)
+ {
+ q = p;
+ p = g_build_path (";", q, g_build_filename (pUsrHome, "Plugins", "VST", 0), 0);
+ }
+ }
+ }
+
+ if (p) //VST
+ g_array_append_val (pFallbackDirs, p);
+ else
+ g_array_append_val (pFallbackDirs, "");
+
+ // BUNDLED_LV2
+ p = g_build_filename(pExeRoot, "bin", "lv2", 0);
+ if (p)
+ g_array_append_val (pFallbackDirs, p);
+ else
+ g_array_append_val (pFallbackDirs, "");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ g_free (pAppData);
+ g_free (pMyAppData);
+ g_free (pExeRoot);
+ g_free (pPersonal);
+ }
+
+ fallback_dir_vector = fallback_folders = (gchar **) g_array_free (pFallbackDirs, FALSE);
+ }
+ }
+ else
+ fallback_dir_vector = fallback_folders;
+
+ return (fallback_dir_vector);
+}
+
+#else
+// Assume Linux, Cygwin or OS-X. Note that in all 3 cases we only
+// need to cater for unbundled releases (those built by a user from
+// source). Bundled releases of Ardour and Mixbus now specifically
+// write their folders and paths to the user's environment at startup.
+// See the function 'fixup_bundle_environment()'.
+
+static gchar**
+get_platform_fallback_folders ()
+{
+gchar **fallback_dir_vector = 0;
+gchar *pUsrHome = 0;
+
+ if (!fallback_folders)
+ {
+ GArray *pFallbackDirs;
+ gchar *pAppData = 0;
+ gchar *pExeRoot = 0;
+ gchar *pPersonal = 0;
+
+ pFallbackDirs = g_array_new (TRUE, TRUE, sizeof (char *));
+
+ if (pFallbackDirs)
+ {
+ pAppData = g_build_filename("/usr", "local", 0);
+ pExeRoot = g_build_filename("/usr", "local", "lib", "ardour2", 0);
+ pPersonal = g_build_filename(g_get_home_dir(), 0);
+
+ if ((pExeRoot) && (pAppData) && (pPersonal))
+ {
+ gchar tmp[PATH_MAX+1];
+ gchar* p;
+
+ // Build our LOCALEDIR entry
+ if (0 != (p = g_build_filename(pAppData, "share", "locale", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our GTK_DIR entry
+ if (0 != (p = g_build_filename(pPersonal, ".gtk-2.0", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our CONFIG_DIR entry
+ if (0 != (p = g_build_filename(pAppData, "etc", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our ARDOUR_DIR entry
+ p = ""; // Empty string (temporary)
+ if (0 != p)
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our MODULE_DIR entry
+ strcpy(tmp, pExeRoot);
+ if (0 != (p = strrchr (tmp, G_DIR_SEPARATOR)))
+ {
+ *p = '\0';
+
+ if (0 != (p = g_build_filename(tmp, 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our DATA_DIR entry
+ if (0 != (p = g_build_filename(pAppData, "share", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our ICONS_DIR entry (re-use 'tmp')
+ strcpy(tmp, "/usr/local/share/ardour2");
+ if (0 != (p = g_build_filename(tmp, "icons", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our PIXMAPS_DIR entry
+ if (0 != (p = g_build_filename(tmp, "pixmaps", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our CONTROL_SURFACES_DIR entry
+ if (0 != (p = g_build_filename(pExeRoot, "surfaces", 0)))
+ {
+ g_array_append_val (pFallbackDirs, p);
+
+ // Build our VAMP_DIR entry
+ p = g_build_filename(pExeRoot, "vamp", 0);
+ if (p)
+ g_array_append_val (pFallbackDirs, p);
+
+ // Next, build our LADSPA_PATH entry
+ p = g_build_filename(Glib::path_get_dirname(pExeRoot).c_str(), "plugins", 0);
+ if (p)
+ g_array_append_val (pFallbackDirs, p);
+
+ // And finally, build our VST_PATH entry
+ if (g_getenv("HOME"))
+ p = g_build_filename(g_getenv("HOME"), "VST", "plugins", 0);
+ else
+ p = g_build_filename(g_get_home_dir(), "VST", "plugins", 0);
+
+ if (p)
+ g_array_append_val (pFallbackDirs, p);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ g_free (pAppData);
+ g_free (pExeRoot);
+ g_free (pPersonal);
+ }
+
+ fallback_dir_vector = fallback_folders = (gchar **) g_array_free (pFallbackDirs, FALSE);
+ }
+ }
+ else
+ fallback_dir_vector = fallback_folders;
+
+ if (pUsrHome)
+ g_free (pUsrHome);
+
+ return (fallback_dir_vector);
+}
+#endif
+
+
+//***************************************************************
+//
+// get_platform_fallback_folder()
+//
+// Returns a const gchar* which points to a string describing
+// the full path to the Ardour fallback folder corresponding to
+// the supplied index. See 'get_platform_fallback_folders()' for a
+// complete list of the supported index enumerations. Calling this
+// function will initialize the fallback folder array if it wasn't
+// already initiaized. The array should then (eventually) be freed
+// using 'free_platform_fallback_folders()'.
+//
+// Returns:
+//
+// On Success: A pointer to the path string contained at the
+// relevant index.
+// On Failure: NULL
+//
+PBD_API G_CONST_RETURN gchar* PBD_APICALLTYPE
+get_platform_fallback_folder (PBD::fallback_folder_t index)
+{
+ if ((index >= 0) && (index < FALLBACK_FOLDER_MAX))
+ return ((G_CONST_RETURN gchar *)get_platform_fallback_folders ()[index]);
+ else
+ return (G_CONST_RETURN gchar *) 0;
+}
+
+
+//***************************************************************
+//
+// alloc_platform_fallback_folders()
+//
+// Calls 'get_platform_fallback_folders()' to ensure that memory
+// for the fallback folder array is already allocated before the
+// array gets used. It doesn't cause any problems if the array gets
+// used prior to calling this function (since the memory will get
+// allocated anyway, on fist usage). Either way however, the momory
+// must later be freed using 'free_platform_fallback_folders()'.
+//
+// Returns:
+//
+// The value obtained from 'get_platform_fallback_folders()'
+//
+PBD_API G_CONST_RETURN gchar* G_CONST_RETURN * PBD_APICALLTYPE
+alloc_platform_fallback_folders ()
+{
+ return ((G_CONST_RETURN gchar* G_CONST_RETURN *)get_platform_fallback_folders ());
+}
+
+
+//***************************************************************
+//
+// free_platform_fallback_folders()
+//
+// Frees the memory that was previously allocated for the Ardour
+// fallback folder array.
+//
+// Returns:
+//
+// NONE.
+//
+PBD_API void PBD_APICALLTYPE
+free_platform_fallback_folders ()
+{
+int index = FOLDER_LOCALE;
+
+ if (fallback_folders)
+ {
+ gchar *p = get_platform_fallback_folders()[(fallback_folder_t)index++];
+
+ while (index < (FALLBACK_FOLDER_MAX+1)) {
+ if (p)
+ g_free (p);
+
+ if (index < FALLBACK_FOLDER_MAX)
+ p = get_platform_fallback_folders()[(fallback_folder_t)index++];
+ else
+ break;
+ }
+
+ fallback_folders = 0;
+ }
+}
+
+} // namespace PBD
+
--- /dev/null
+/*
+ Copyright (C) 2013 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 "pbd/ffs.h"
+
+#ifndef COMPILER_MSVC
+#include <strings.h>
+#endif
+
+namespace PBD {
+int
+ffs (int x)
+{
+#if defined (COMPILER_MINGW)
+ return __builtin_ffs(x);
+#elif defined (COMPILER_MSVC)
+ unsigned long index;
+#ifdef WIN64
+ if (0 != _BitScanForward64(&index, (__int64)x))
+#else
+ if (0 != _BitScanForward(&index, (unsigned long)x))
+#endif
+ index++; // Make the result 1-based
+ else
+ index = 0; // All bits were zero
+
+ return (int)index;
+#else
+ return ::ffs(x);
+#endif
+}
+
+}
*/
#include <sys/time.h>
-#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cassert>
#include <cstdio>
+#include <glib.h>
+#include <glib/gstdio.h>
+
#ifdef __APPLE__
#include <mach/mach_time.h>
#endif
#include "pbd/compose.h"
#include "pbd/file_manager.h"
+#include "pbd/resource.h"
#include "pbd/debug.h"
using namespace std;
FileManager::FileManager ()
: _open (0)
{
- struct rlimit rl;
- int const r = getrlimit (RLIMIT_NOFILE, &rl);
+ struct ResourceLimit rl;
/* XXX: this is a bit arbitrary */
- if (r == 0) {
- _max_open = rl.rlim_cur - 64;
+ if (get_resource_limit (OpenFiles, rl)) {
+ _max_open = rl.current_limit - 64;
} else {
_max_open = 256;
}
#ifdef __APPLE__
d->_last_used = mach_absolute_time();
-#else
+#elif defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
struct timespec t;
clock_gettime (CLOCK_MONOTONIC, &t);
d->_last_used = t.tv_sec + (double) t.tv_nsec / 10e9;
+#else
+ struct timeval now;
+ gettimeofday (&now, NULL);
+ d->_last_used = now.tv_sec + (double) now.tv_usec / 10e6;
#endif
d->_refcount++;
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);
}
#include <glib.h>
#include <glib/gstdio.h>
+#ifdef COMPILER_MINGW
+#include <io.h> // For W_OK
+#endif
+
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
#include <glibmm/pattern.h>
#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"
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);
}
}
}
void
-find_matching_files_in_search_path (const SearchPath& search_path,
+find_matching_files_in_search_path (const Searchpath& search_path,
const Glib::PatternSpec& pattern,
vector<std::string>& result)
{
}
bool
-find_file_in_search_path(const SearchPath& search_path,
+find_file_in_search_path(const Searchpath& search_path,
const string& filename,
std::string& result)
{
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;
}
bool
equivalent_paths (const std::string& a, const std::string& b)
{
- struct stat bA;
+ GStatBuf bA;
int const rA = g_stat (a.c_str(), &bA);
- struct stat bB;
+ GStatBuf bB;
int const rB = g_stat (b.c_str(), &bB);
return (rA == 0 && rB == 0 && bA.st_dev == bB.st_dev && bA.st_ino == bB.st_ino);
make us unwritable.
*/
- struct stat statbuf;
+ GStatBuf statbuf;
if (g_stat (p.c_str(), &statbuf) != 0) {
/* doesn't exist - not writable */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
+#ifndef COMPILER_MSVC
#include "libpbd-config.h"
#define _XOPEN_SOURCE 600
FPU::~FPU ()
{
}
+
+#else // COMPILER_MSVC
+ const char* pbd_fpu = "pbd/msvc/fpu.cc takes precedence over this file";
+#endif // COMPILER_MSVC
--- /dev/null
+/*
+ Copyright (C) 2010 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 "pbd/glib_semaphore.h"
+
+namespace PBD {
+
+GlibSemaphore::GlibSemaphore (gint initial_val)
+ :
+ m_counter(initial_val)
+{ }
+
+void
+GlibSemaphore::wait ()
+{
+ Glib::Threads::Mutex::Lock guard (m_mutex);
+
+ while (m_counter.get() < 1) {
+ m_cond.wait(m_mutex);
+ }
+
+ // this shouldn't need to be inside the lock
+ --m_counter;
+}
+
+bool
+GlibSemaphore::try_wait ()
+{
+ if (!m_mutex.trylock())
+ {
+ return false;
+ }
+ // lock successful
+ while (m_counter.get() < 1) {
+ m_cond.wait(m_mutex);
+ }
+
+ // the order of these should not matter
+ --m_counter;
+ m_mutex.unlock();
+ return true;
+}
+
+void
+GlibSemaphore::post ()
+{
+ // atomic, no locking required
+ ++m_counter;
+ m_cond.signal();
+}
+
+} // namespace PBD
--- /dev/null
+#include <cstring>
+#include <locale.h>
+#include <stdlib.h>
+
+#include "pbd/localeguard.h"
+
+// JE - added temporarily, to reduce the delay effects when calling
+// setlocale() recursively in a Windows GUI thread (we should think
+// about moving the caller(s) into a dedicated worker thread).
+std::string PBD::LocaleGuard::current;
+
+PBD::LocaleGuard::LocaleGuard (const char* str)
+ : old(0)
+{
+ if (current != str) {
+ old = strdup (setlocale (LC_NUMERIC, NULL));
+ if (strcmp (old, str)) {
+ if (setlocale (LC_NUMERIC, str))
+ current = str;
+ }
+ }
+}
+
+PBD::LocaleGuard::~LocaleGuard ()
+{
+ if (old) {
+ if (setlocale (LC_NUMERIC, old))
+ current = old;
+
+ free ((char*)old);
+ }
+}
+
+
--- /dev/null
+#ifdef WAF_BUILD
+#include "libpbd-config.h"
+#endif
+
+#ifndef HAVE_LOCALTIME_R
+#include <time.h>
+#include <string.h>
+
+#include "pbd/pthread_utils.h"
+#include "pbd/localtime_r.h"
+
+#ifdef localtime_r
+#undef localtime_r
+#endif
+
+struct tm *
+localtime_r(const time_t *const timep, struct tm *p_tm)
+{
+ static pthread_mutex_t time_mutex;
+ static int time_mutex_inited = 0;
+ struct tm *tmp;
+
+ if (!time_mutex_inited)
+ {
+ time_mutex_inited = 1;
+ pthread_mutex_init(&time_mutex, NULL);
+ }
+
+ pthread_mutex_lock(&time_mutex);
+ tmp = localtime(timep);
+ if (tmp)
+ {
+ memcpy(p_tm, tmp, sizeof(struct tm));
+ tmp = p_tm;
+ }
+ pthread_mutex_unlock(&time_mutex);
+
+ return tmp;
+}
+
+#endif
$Id$
*/
-
+#ifndef COMPILER_MSVC
#include <cstdio>
#include <cstring>
#include <string>
return best;
}
+#elif defined(PLATFORM_WINDOWS)
+
+string
+mountpoint (string path)
+{
+ // TODO ... if needed
+}
+
#else // !HAVE_GETMNTENT
#include <sys/param.h>
}
#endif // TEST_MOUNTPOINT
+
+#else // COMPILER_MSVC
+ const char* pbd_mountpoint = "pbd/msvc/mountpoint.cc takes precedence over this file";
+#endif // COMPILER_MSVC
--- /dev/null
+#ifdef COMPILER_MSVC // Added by JE - 05-12-2009. Inline assembler instructions
+ // have been changed to Intel format and (in the case of
+ // cpuid) was replaced by the equivalent VC++ system call).
+#define _XOPEN_SOURCE 600
+#include <cstdlib>
+#include <stdint.h>
+#include <intrin.h> // Added by JE - 05-12-2009
+
+#include <pbd/fpu.h>
+#include <pbd/error.h>
+
+#include "i18n.h"
+
+using namespace PBD;
+using namespace std;
+
+FPU::FPU ()
+{
+ unsigned long cpuflags = 0;
+
+ _flags = (Flags)0;
+
+#ifndef ARCH_X86
+ return;
+
+#else
+
+#ifndef USE_X86_64_ASM
+int cpuInfo[4];
+
+ __cpuid (cpuInfo, 1);
+ cpuflags = cpuInfo[3];
+/*
+ __asm { // This is how the original section would look if converted to Intel syntax.
+ // However, I have grave doubts about whether it's doing the right thing.
+ // It seems as if the intention was to retrieve feature information from
+ // the processor. However, feature information is returned in the ebx register
+ // (if you believe Wikipedia) or in edx (if you believe Microsoft). Unfortunately,
+ // both registers get ignored in the original code!! Confused?? Join the club!!
+ mov eax, 1
+ push ebx
+ cpuid
+ mov edx, 0
+ pop ebx
+ mov cpuflags, ecx // This can't be right, surely???
+ }; */
+#else
+// Note that this syntax is currently still in AT&T format !
+ asm volatile (
+ "pushq %%rbx\n"
+ "movq $1, %%rax\n"
+ "cpuid\n"
+ "movq %%rdx, %0\n"
+ "popq %%rbx\n"
+ : "=r" (cpuflags)
+ :
+ : "%rax", "%rcx", "%rdx", "memory"
+ );
+
+#endif /* USE_X86_64_ASM */
+
+ if (cpuflags & (1<<25)) {
+ _flags = Flags (_flags | (HasSSE|HasFlushToZero));
+ }
+
+ if (cpuflags & (1<<26)) {
+ _flags = Flags (_flags | HasSSE2);
+ }
+
+ if (cpuflags & (1 << 24)) {
+ bool aligned_malloc = false; // Added by JE - 05-12-2009
+ char* fxbuf = 0;
+// This section changed by JE - 05-12-2009
+#ifdef NO_POSIX_MEMALIGN
+#if defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // All of these support '_aligned_malloc()'
+ fxbuf = (char *) _aligned_malloc(512, 16); // (note that they all need at least MSVC runtime 7.0)
+ aligned_malloc = true;
+#else
+ fxbuf = (char *) malloc(512);
+#endif
+#else
+ fxbuf = posix_memalign ((void**)&fxbuf, 16, 512);
+#endif
+ // Verify that fxbuf is correctly aligned
+ unsigned long buf_addr = (unsigned long)(void*)fxbuf;
+ if ((0 == buf_addr) || (buf_addr % 16))
+ error << _("cannot allocate 16 byte aligned buffer for h/w feature detection") << endmsg;
+ else
+ {
+ memset(fxbuf, 0, 512); // Initialize the buffer !!! Added by JE - 12-12-2009
+
+ __asm {
+ mov eax, fxbuf
+ fxsave [eax]
+ };
+
+ uint32_t mxcsr_mask = *((uint32_t*) &fxbuf[28]);
+
+ /* if the mask is zero, set its default value (from intel specs) */
+
+ if (mxcsr_mask == 0) {
+ mxcsr_mask = 0xffbf;
+ }
+
+ if (mxcsr_mask & (1<<6)) {
+ _flags = Flags (_flags | HasDenormalsAreZero);
+ }
+
+ if (aligned_malloc)
+ _aligned_free (fxbuf);
+ else
+ free (fxbuf);
+ }
+ }
+#endif // ARCH_X86
+}
+
+FPU::~FPU ()
+{
+}
+
+#else // !COMPILER_MSVC
+ const char* pbd_fpu = "original pbd/fpu.cc takes precedence over this file";
+#endif // COMPILER_MSVC
--- /dev/null
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef COMPILER_MSVC
+#include "pbd/msvc_pbd.h"
+#endif
+#include "getopt.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+__BEGIN_DECLS // Added by JE - 31-01-2010
+// All 'GETOPT_API' declarations added by JE - 31-01-2010
+GETOPT_API int opterr = 1; /* if error message should be printed */
+GETOPT_API int optind = 1; /* index into parent argv vector */
+GETOPT_API int optopt; /* character checked for validity */
+GETOPT_API int optreset; /* reset getopt */
+GETOPT_API char *optarg; /* argument associated with option */
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt(int nargc, // Argument list ratified by JE - 03-01-2010
+ char * const *nargv,
+ const char *ostr)
+{
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = EMSG;
+ return (-1);
+ }
+ if (place[1] && *++place == '-') { /* found "--" */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' ||
+ !(oli = (char*)strchr(ostr, optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means -1.
+ */
+ if (optopt == (int)'-')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (opterr && *ostr != ':' && optopt != BADCH)
+ (void)fprintf(stderr, "%s: illegal option -- %c\n",
+ "progname", optopt);
+ return (BADCH);
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place)
+ ++optind;
+ }
+ else { /* need an argument */
+ if (*place) /* no white space */
+ optarg = place;
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ "progname", optopt);
+ return (BADCH);
+ }
+ else /* white space */
+ optarg = nargv[optind];
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* dump back option letter */
+}
+__END_DECLS // Added by JE - 31-01-2010
--- /dev/null
+/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
+/* $FreeBSD: src/include/getopt.h,v 1.1 2002/09/29 04:14:30 eric Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+#ifdef PLATFORM_WINDOWS
+/* from <sys/cdefs.h> */
+# ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+# else
+# define __BEGIN_DECLS
+# define __END_DECLS
+# endif
+# define __P(args) args
+#endif
+
+/*#ifndef PLATFORM_WINDOWS
+#include <sys/cdefs.h>
+#include <unistd.h>
+#endif*/
+
+#ifdef PLATFORM_WINDOWS
+# if !defined(GETOPT_API)
+# define GETOPT_API __declspec(dllimport)
+# endif
+#endif
+
+/*
+ * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions
+ */
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+struct option {
+ /* name of long option */
+ const char *name;
+ /*
+ * one of no_argument, required_argument, and optional_argument:
+ * whether option takes an argument
+ */
+ int has_arg;
+ /* if not NULL, set *flag to val when option found */
+ int *flag;
+ /* if flag not NULL, value to set *flag to; else return value */
+ int val;
+};
+
+__BEGIN_DECLS
+GETOPT_API int getopt_long __P((int, char * const *, const char *,
+ const struct option *, int *));
+__END_DECLS
+#endif
+
+#ifdef PLATFORM_WINDOWS
+/* These are global getopt variables */
+__BEGIN_DECLS
+
+GETOPT_API extern int opterr, /* if error message should be printed */
+ optind, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+GETOPT_API extern char* optarg; /* argument associated with option */
+
+/* Original getopt */
+GETOPT_API int getopt __P((int, char * const *, const char *));
+
+__END_DECLS
+#endif
+
+#endif /* !_GETOPT_H_ */
--- /dev/null
+/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
+/* $FreeBSD: src/lib/libc/stdlib/getopt_long.c,v 1.2 2002/10/16 22:18:42 alfred Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef PLATFORM_WINDOWS
+#ifdef COMPILER_MSVC
+#include "pbd/msvc_pbd.h" // Defines 'GETOPT_API'
+#endif
+/* Windows needs warnx(). We change the definition though:
+ * 1. (another) global is defined, opterrmsg, which holds the error message
+ * 2. errors are always printed out on stderr w/o the program name
+ * Note that opterrmsg always gets set no matter what opterr is set to. The
+ * error message will not be printed if opterr is 0 as usual.
+ */
+
+#include "getopt.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+GETOPT_API extern char opterrmsg[128];
+char opterrmsg[128]; /* last error message is stored here */
+
+static void warnx(int print_error, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ if (fmt != NULL)
+ _vsnprintf(opterrmsg, 128, fmt, ap);
+ else
+ opterrmsg[0]='\0';
+ va_end(ap);
+ if (print_error) {
+ fprintf(stderr, opterrmsg);
+ fprintf(stderr, "\n");
+ }
+}
+
+#endif /*PLATFORM_WINDOWS*/
+
+/* not part of the original file */
+#ifndef _DIAGASSERT
+#define _DIAGASSERT(X)
+#endif
+
+#if HAVE_CONFIG_H && !HAVE_GETOPT_LONG && !HAVE_DECL_OPTIND
+#define REPLACE_GETOPT
+#endif
+
+#ifdef REPLACE_GETOPT
+#ifdef __weak_alias
+__weak_alias(getopt,_getopt)
+#endif
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+int optopt = '?'; /* character checked for validity */
+int optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+#elif HAVE_CONFIG_H && !HAVE_DECL_OPTRESET
+static int optreset;
+#endif
+
+#ifdef __weak_alias
+__weak_alias(getopt_long,_getopt_long)
+#endif
+
+#if !HAVE_GETOPT_LONG
+#define IGNORE_FIRST (*options == '-' || *options == '+')
+#define PRINT_ERROR ((opterr) && ((*options != ':') \
+ || (IGNORE_FIRST && options[1] != ':')))
+#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL)
+#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST)
+/* XXX: GNU ignores PC if *options == '-' */
+#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-')
+
+/* return values */
+#define BADCH (int)'?'
+#define BADARG ((IGNORE_FIRST && options[1] == ':') \
+ || (*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#define EMSG ""
+
+static int getopt_internal(int, char * const *, const char *);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1; /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+ int c;
+
+ c = a % b;
+ while (c != 0) {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return b;
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start,
+ int panonopt_end,
+ int opt_end,
+ char * const *nargv)
+{
+ int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+ char *swap;
+
+ _DIAGASSERT(nargv != NULL);
+
+ /*
+ * compute lengths of blocks and number and size of cycles
+ */
+ nnonopts = panonopt_end - panonopt_start;
+ nopts = opt_end - panonopt_end;
+ ncycle = gcd(nnonopts, nopts);
+ cyclelen = (opt_end - panonopt_start) / ncycle;
+
+ for (i = 0; i < ncycle; i++) {
+ cstart = panonopt_end+i;
+ pos = cstart;
+ for (j = 0; j < cyclelen; j++) {
+ if (pos >= panonopt_end)
+ pos -= nnonopts;
+ else
+ pos += nopts;
+ swap = nargv[pos];
+ /* LINTED const cast */
+ ((char **) nargv)[pos] = nargv[cstart];
+ /* LINTED const cast */
+ ((char **)nargv)[cstart] = swap;
+ }
+ }
+}
+
+/*
+ * getopt_internal --
+ * Parse argc/argv argument vector. Called by user level routines.
+ * Returns -2 if -- is found (can be long option or end of options marker).
+ */
+static int
+getopt_internal(int nargc,
+ char * const *nargv,
+ const char *options)
+{
+ char *oli; /* option letter list index */
+ int optchar;
+
+ _DIAGASSERT(nargv != NULL);
+ _DIAGASSERT(options != NULL);
+
+ optarg = NULL;
+
+ /*
+ * XXX Some programs (like rsyncd) expect to be able to
+ * XXX re-initialize optind to 0 and have getopt_long(3)
+ * XXX properly function again. Work around this braindamage.
+ */
+ if (optind == 0)
+ optind = 1;
+
+ if (optreset)
+ nonopt_start = nonopt_end = -1;
+start:
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc) { /* end of argument vector */
+ place = EMSG;
+ if (nonopt_end != -1) {
+ /* do permutation, if we have to */
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ else if (nonopt_start != -1) {
+ /*
+ * If we skipped non-options, set optind
+ * to the first of them.
+ */
+ optind = nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return -1;
+ }
+ if ((*(place = nargv[optind]) != '-')
+ || (place[1] == '\0')) { /* found non-option */
+ place = EMSG;
+ if (IN_ORDER) {
+ /*
+ * GNU extension:
+ * return non-option as argument to option 1
+ */
+ optarg = nargv[optind++];
+ return INORDER;
+ }
+ if (!PERMUTE) {
+ /*
+ * if no permutation wanted, stop parsing
+ * at first non-option
+ */
+ return -1;
+ }
+ /* do permutation */
+ if (nonopt_start == -1)
+ nonopt_start = optind;
+ else if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ nonopt_start = optind -
+ (nonopt_end - nonopt_start);
+ nonopt_end = -1;
+ }
+ optind++;
+ /* process next argument */
+ goto start;
+ }
+ if (nonopt_start != -1 && nonopt_end == -1)
+ nonopt_end = optind;
+ if (place[1] && *++place == '-') { /* found "--" */
+ place++;
+ return -2;
+ }
+ }
+ if ((optchar = (int)*place++) == (int)':' ||
+ (oli = (char*)strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
+ /* option letter unknown or ':' */
+ if (!*place)
+ ++optind;
+#ifndef PLATFORM_WINDOWS
+ if (PRINT_ERROR)
+ warnx(illoptchar, optchar);
+#else
+ warnx(PRINT_ERROR, illoptchar, optchar);
+#endif
+ optopt = optchar;
+ return BADCH;
+ }
+ if (optchar == 'W' && oli[1] == ';') { /* -W long-option */
+ /* XXX: what if no long options provided (called by getopt)? */
+ if (*place)
+ return -2;
+
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+#ifndef PLATFORM_WINDOWS
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+#else
+ warnx(PRINT_ERROR, recargchar, optchar);
+#endif
+ optopt = optchar;
+ return BADARG;
+ } else /* white space */
+ place = nargv[optind];
+ /*
+ * Handle -W arg the same as --arg (which causes getopt to
+ * stop parsing).
+ */
+ return -2;
+ }
+ if (*++oli != ':') { /* doesn't take argument */
+ if (!*place)
+ ++optind;
+ } else { /* takes (optional) argument */
+ optarg = NULL;
+ if (*place) /* no white space */
+ optarg = place;
+ /* XXX: disable test for :: if PC? (GNU doesn't) */
+ else if (oli[1] != ':') { /* arg not optional */
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+#ifndef PLATFORM_WINDOWS
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+#else
+ warnx(PRINT_ERROR, recargchar, optchar);
+#endif
+ optopt = optchar;
+ return BADARG;
+ } else
+ optarg = nargv[optind];
+ }
+ place = EMSG;
+ ++optind;
+ }
+ /* dump back option letter */
+ return optchar;
+}
+
+__BEGIN_DECLS // Added by JE - 31-01-2010
+#ifdef REPLACE_GETOPT
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the real getopt]
+ */
+GETOPT_API int // 'GETOPT_API' declaration added by JE - 31-01-2010
+getopt(int nargc,
+ char * const *nargv,
+ const char *options)
+{
+ int retval;
+
+ _DIAGASSERT(nargv != NULL);
+ _DIAGASSERT(options != NULL);
+
+ if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
+ ++optind;
+ /*
+ * We found an option (--), so if we skipped non-options,
+ * we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end, optind,
+ nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ retval = -1;
+ }
+ return retval;
+}
+#endif
+
+/*
+ * getopt_long --
+ * Parse argc/argv argument vector.
+ */
+GETOPT_API int // 'GETOPT_API' declaration added by JE - 31-01-2010
+getopt_long(int nargc,
+ char * const *nargv,
+ const char *options,
+ const struct option *long_options,
+ int *idx)
+{
+ int retval;
+
+ _DIAGASSERT(nargv != NULL);
+ _DIAGASSERT(options != NULL);
+ _DIAGASSERT(long_options != NULL);
+ /* idx may be NULL */
+
+ if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
+ char *current_argv, *has_equal;
+ size_t current_argv_len;
+ int i, match;
+
+ current_argv = place;
+ match = -1;
+
+ optind++;
+ place = EMSG;
+
+ if (*current_argv == '\0') { /* found "--" */
+ /*
+ * We found an option (--), so if we skipped
+ * non-options, we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return -1;
+ }
+ if ((has_equal = strchr(current_argv, '=')) != NULL) {
+ /* argument found (--option=arg) */
+ current_argv_len = has_equal - current_argv;
+ has_equal++;
+ } else
+ current_argv_len = strlen(current_argv);
+
+ for (i = 0; long_options[i].name; i++) {
+ /* find matching long option */
+ if (strncmp(current_argv, long_options[i].name,
+ current_argv_len))
+ continue;
+
+ if (strlen(long_options[i].name) ==
+ (unsigned)current_argv_len) {
+ /* exact match */
+ match = i;
+ break;
+ }
+ if (match == -1) /* partial match */
+ match = i;
+ else {
+ /* ambiguous abbreviation */
+#ifndef PLATFORM_WINDOWS
+ if (PRINT_ERROR)
+ warnx(ambig, (int)current_argv_len,
+ current_argv);
+#else
+ warnx(PRINT_ERROR, ambig, (int)current_argv_len,
+ current_argv);
+#endif
+ optopt = 0;
+ return BADCH;
+ }
+ }
+ if (match != -1) { /* option found */
+ if (long_options[match].has_arg == no_argument
+ && has_equal) {
+#ifndef PLATFORM_WINDOWS
+ if (PRINT_ERROR)
+ warnx(noarg, (int)current_argv_len,
+ current_argv);
+#else
+ warnx(PRINT_ERROR, noarg, (int)current_argv_len,
+ current_argv);
+#endif
+ /*
+ * XXX: GNU sets optopt to val regardless of
+ * flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ return BADARG;
+ }
+ if (long_options[match].has_arg == required_argument ||
+ long_options[match].has_arg == optional_argument) {
+ if (has_equal)
+ optarg = has_equal;
+ else if (long_options[match].has_arg ==
+ required_argument) {
+ /*
+ * optional argument doesn't use
+ * next nargv
+ */
+ optarg = nargv[optind++];
+ }
+ }
+ if ((long_options[match].has_arg == required_argument)
+ && (optarg == NULL)) {
+ /*
+ * Missing argument; leading ':'
+ * indicates no error should be generated
+ */
+#ifndef PLATFORM_WINDOWS
+ if (PRINT_ERROR)
+ warnx(recargstring, current_argv);
+#else
+ warnx(PRINT_ERROR, recargstring, current_argv);
+#endif
+ /*
+ * XXX: GNU sets optopt to val regardless
+ * of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ --optind;
+ return BADARG;
+ }
+ } else { /* unknown option */
+#ifndef PLATFORM_WINDOWS
+ if (PRINT_ERROR)
+ warnx(illoptstring, current_argv);
+#else
+ warnx(PRINT_ERROR, illoptstring, current_argv);
+#endif
+ optopt = 0;
+ return BADCH;
+ }
+ if (long_options[match].flag) {
+ *long_options[match].flag = long_options[match].val;
+ retval = 0;
+ } else
+ retval = long_options[match].val;
+ if (idx)
+ *idx = match;
+ }
+ return retval;
+}
+__END_DECLS // Added by JE - 31-01-2010
+
+#endif /* !GETOPT_LONG */
--- /dev/null
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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.
+
+ $Id: mountpoint.cc 3920 2008-10-11 12:34:46Z paul $
+*/
+
+#ifdef COMPILER_MSVC
+
+/* TODO - Still to be implemented */
+
+#include <cstdio>
+#include <cstring>
+#include <string>
+#include <cstring>
+#include <limits.h>
+
+#include <pbd/mountpoint.h>
+
+using std::string;
+
+#if HAVE_GETMNTENT
+#include <mntent.h>
+
+struct mntent_sorter {
+ bool operator() (const mntent *a, const mntent *b) {
+ return strcmp (a->mnt_dir, b->mnt_dir);
+ }
+};
+
+string
+mountpoint (string path)
+{
+ FILE *mntf;
+ mntent *mnt;
+ unsigned int maxmatch = 0;
+ unsigned int matchlen;
+ const char *cpath = path.c_str();
+ char best[PATH_MAX+1];
+
+ if ((mntf = setmntent ("/etc/mtab", "r")) == 0) {
+ return "";
+ }
+
+ best[0] = '\0';
+
+ while ((mnt = getmntent (mntf))) {
+ unsigned int n;
+
+ n = 0;
+ matchlen = 0;
+
+ /* note: strcmp's semantics are not
+ strict enough to use for this.
+ */
+
+ while (cpath[n] && mnt->mnt_dir[n]) {
+ if (cpath[n] != mnt->mnt_dir[n]) {
+ break;
+ }
+ matchlen++;
+ n++;
+ }
+
+ if (cpath[matchlen] == '\0') {
+
+ endmntent (mntf);
+ return mnt->mnt_dir;
+
+ } else {
+
+ if (matchlen > maxmatch) {
+ snprintf (best, sizeof(best), "%s", mnt->mnt_dir);
+ maxmatch = matchlen;
+ }
+ }
+ }
+
+ endmntent (mntf);
+
+ return best;
+}
+
+#else // !HAVE_GETMNTENT
+
+string
+mountpoint (string path)
+{
+return "";
+
+/* // The rest is commented out temporarily by JE - 30-11-2009
+ // (I think this must be the implementation for MacOS).
+ struct statfs *mntbufp = 0;
+ int count;
+ unsigned int maxmatch = 0;
+ unsigned int matchlen;
+ const char *cpath = path.c_str();
+ char best[PATH_MAX+1];
+
+ if ((count = getmntinfo(&mntbufp, MNT_NOWAIT)) == 0) {
+ free(mntbufp);
+ return "\0";
+ }
+
+ best[0] = '\0';
+
+ for (int i = 0; i < count; ++i) {
+ unsigned int n = 0;
+ matchlen = 0;
+
+ // note: strcmp's semantics are not
+ // strict enough to use for this.
+
+ while (cpath[n] && mntbufp[i].f_mntonname[n]) {
+ if (cpath[n] != mntbufp[i].f_mntonname[n]) {
+ break;
+ }
+ matchlen++;
+ n++;
+ }
+
+ if (cpath[matchlen] == '\0') {
+ snprintf(best, sizeof(best), "%s", mntbufp[i].f_mntonname);
+ free(mntbufp);
+ return best;
+
+ } else {
+
+ if (matchlen > maxmatch) {
+ snprintf (best, sizeof(best), "%s", mntbufp[i].f_mntonname);
+ maxmatch = matchlen;
+ }
+ }
+ }
+
+ return best;
+*/
+}
+#endif // HAVE_GETMNTENT
+
+#ifdef TEST_MOUNTPOINT
+
+main (int argc, char *argv[])
+{
+ printf ("mp of %s = %s\n", argv[1], mountpoint (argv[1]).c_str());
+ exit (0);
+}
+
+#endif // TEST_MOUNTPOINT
+
+#else // !COMPILER_MSVC
+ const char* pbd_mountpoint = "original pbd/mountpoint.cc takes precedence over this file";
+#endif // COMPILER_MSVC
--- /dev/null
+/*
+ Copyright (C) 2009 John Emmas
+
+ 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 COMPILER_MSVC
+
+#include <WTypes.h>
+
+extern "C" WINBASEAPI BOOL WINAPI
+CreateHardLinkA( LPCSTR lpFileName,
+ LPCSTR lpExistingFileName,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes ); // Needs kernel32.lib on anything higher than Win2K
+
+#include <algorithm>
+#include <string>
+#include <io.h>
+#include <math.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <pbd/error.h>
+#include <ardourext/misc.h>
+#include <ardourext/pthread.h> // Should ensure that we include the right
+ // version - but we'll check anyway, later
+
+#include <glibmm.h>
+
+#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
+
+struct timezone
+{
+ int tz_minuteswest; /* minutes W of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+
+PBD_API int PBD_APICALLTYPE
+gettimeofday(struct timeval *__restrict tv, __timezone_ptr_t tz) // Does this need to be exported ?
+{
+FILETIME ft;
+unsigned __int64 tmpres = 0;
+static int tzflag = 0;
+
+ if (NULL != tv)
+ {
+ GetSystemTimeAsFileTime(&ft);
+
+ tmpres |= ft.dwHighDateTime;
+ tmpres <<= 32;
+ tmpres |= ft.dwLowDateTime;
+
+ /*converting file time to unix epoch*/
+ tmpres /= 10; /*convert into microseconds*/
+ tmpres -= DELTA_EPOCH_IN_MICROSECS;
+ tv->tv_sec = (long)(tmpres / 1000000UL);
+ tv->tv_usec = (long)(tmpres % 1000000UL);
+ }
+
+ if (NULL != tz)
+ {
+ struct timezone *ptz = static_cast<struct timezone*> (tz);
+ if (!tzflag)
+ {
+ _tzset();
+ tzflag++;
+ }
+ if (ptz)
+ {
+ ptz->tz_minuteswest = _timezone / 60;
+ ptz->tz_dsttime = _daylight;
+ }
+ }
+
+ return 0;
+}
+
+// Define the default comparison operators for Windows (ptw32) 'pthread_t' (not used
+// by Ardour AFAIK but would be needed if an array of 'pthread_t' had to be sorted).
+#ifndef PTHREAD_H // Defined by PTW32 (Linux and other versions define _PTHREAD_H)
+#error "An incompatible version of 'pthread.h' is #included. Use only the Windows (ptw32) version!"
+#else
+bool operator> (const pthread_t& lhs, const pthread_t& rhs)
+{
+ return (std::greater<void*>()(lhs.p, rhs.p));
+}
+
+bool operator< (const pthread_t& lhs, const pthread_t& rhs)
+{
+ return (std::less<void*>()(lhs.p, rhs.p));
+}
+
+bool operator!= (const pthread_t& lhs, const pthread_t& rhs)
+{
+ return (std::not_equal_to<void*>()(lhs.p, rhs.p));
+}
+
+bool operator== (const pthread_t& lhs, const pthread_t& rhs)
+{
+ return (!(lhs != rhs));
+}
+#endif
+
+// Functions supplied (later) to std::transform
+//***************************************************************
+//
+// invert_backslash()
+//
+// Examines a supplied ASCII character and (if the character is
+// a backslash) converts it to a forward slash,
+//
+// Returns:
+//
+// The supplied character (converted, if it was a backslash)
+//
+char invert_backslash(char character)
+{
+ if ('\\' == character)
+ character = '/';
+
+ return (character);
+}
+
+//***************************************************************
+//
+// invert_forwardslash()
+//
+// Examines a supplied ASCII character and (if the character is
+// a forward slash) converts it to a backslash,
+//
+// Returns:
+//
+// The supplied character (converted, if it was a fwd slash)
+//
+char invert_forwardslash(char character)
+{
+ if ('/' == character)
+ character = '\\';
+
+ return (character);
+}
+
+
+//***************************************************************
+//
+// pread()
+//
+// Emulates pread() using _lseek()/_read()/_lseek().
+//
+// Returns:
+//
+// On Success: The number of bytes read from the file
+// On Failure: -1
+//
+PBD_API ssize_t PBD_APICALLTYPE
+pread(int handle, void *buf, size_t nbytes, off_t offset)
+{
+int old_errno;
+ssize_t ret;
+
+ off_t old_offset = _tell(handle);
+
+ if (0 > old_offset)
+ ret = (-1);
+ else
+ {
+ _lseek(handle, offset, SEEK_SET);
+ ret = _read(handle, buf, nbytes);
+
+ old_errno = errno;
+ _lseek(handle, old_offset, SEEK_SET);
+ errno = old_errno;
+ }
+
+ return (ret);
+}
+
+
+//***************************************************************
+//
+// pwrite()
+//
+// Emulates pwrite() using _lseek()/_write()/_lseek().
+//
+// Returns:
+//
+// On Success: The number of bytes written to the file
+// On Failure: -1
+//
+PBD_API ssize_t PBD_APICALLTYPE
+pwrite(int handle, const void *buf, size_t nbytes, off_t offset)
+{
+int old_errno;
+ssize_t ret;
+
+ off_t old_offset = _lseek(handle, offset, SEEK_SET);
+
+ if (0 > old_offset)
+ ret = (-1);
+ else
+ {
+ ret = _write(handle, buf, nbytes);
+
+ old_errno = errno;
+ _lseek(handle, old_offset, SEEK_SET);
+ errno = old_errno;
+ }
+
+ return (ret);
+}
+
+//***************************************************************
+//
+// round()
+//
+// Emulates round() using floor().
+//
+// Returns:
+//
+// On Success: The largest integer that is less than or
+// equal to 'x'.
+// On Failure: None
+//
+PBD_API double PBD_APICALLTYPE
+round(double x)
+{
+ return (floor(x));
+}
+
+namespace PBD {
+
+//***************************************************************
+//
+// TestForMinimumSpecOS()
+//
+// Tests the user's OS to see if it is Win2K or later (could be
+// expanded quite easily to accommodate other OS's)
+//
+// Returns:
+//
+// On Success: TRUE (if the user's OS matches the minimum spec)
+// On Failure: FALSE otherwise
+//
+PBD_API bool PBD_APICALLTYPE
+TestForMinimumSpecOS(char *revision /* currently ignored */)
+{
+bool bRet = true;
+#ifdef PLATFORM_WINDOWS
+ bRet = false;
+ HINSTANCE hKernelDll = (HINSTANCE)dlopen("kernel32.dll", RTLD_NOW);
+
+ if (hKernelDll)
+ {
+ // 'CreateHardLink()' is only available from Win2K onwards.
+ if (NULL != dlsym(hKernelDll, "CreateHardLinkA"))
+ bRet = true;
+
+ dlclose(hKernelDll);
+ }
+#endif
+ // Other OS's could be accommodated here
+
+ return (bRet);
+}
+
+
+//***************************************************************
+//
+// realpath()
+//
+// Emulates POSIX realpath() using Win32 _fullpath().
+//
+// Returns:
+//
+// On Success: A pointer to the resolved (absolute) path
+// On Failure: NULL
+//
+PBD_API char* PBD_APICALLTYPE
+realpath (const char *original_path, char resolved_path[_MAX_PATH+1])
+{
+char *pRet = NULL;
+bool bIsSymLink = 0; // We'll probably need to test the incoming path
+ // to find out if it points to a Windows shortcut
+ // (or a hard link) and set this appropriately.
+ if (bIsSymLink)
+ {
+ // At the moment I'm not sure if Windows '_fullpath()' is directly
+ // equivalent to POSIX 'realpath()' - in as much as the latter will
+ // resolve the supplied path if it happens to point to a symbolic
+ // link ('_fullpath()' probably DOESN'T do this but I'm not really
+ // sure if Ardour needs such functionality anyway). Therefore we'll
+ // possibly need to add that functionality here at a later date.
+ }
+ else
+ {
+ char temp[(MAX_PATH+1)*6]; // Allow for maximum length of a path in UTF8 characters
+
+ // POSIX 'realpath()' requires that the buffer size is at
+ // least PATH_MAX+1, so assume that the user knew this !!
+ pRet = _fullpath(temp, Glib::locale_from_utf8(original_path).c_str(), _MAX_PATH);
+ if (NULL != pRet)
+ strcpy(resolved_path, Glib::locale_to_utf8(temp).c_str());
+ }
+
+ return (pRet);
+}
+
+
+//***************************************************************
+//
+// opendir()
+//
+// Creates a pointer to a DIR structure, appropriately filled in
+// and ready to begin a directory search iteration.
+//
+// Returns:
+//
+// On Success: Pointer to a (heap based) DIR structure
+// On Failure: NULL
+//
+PBD_API DIR* PBD_APICALLTYPE
+opendir (const char *szPath)
+{
+wchar_t wpath[PATH_MAX+1];
+unsigned int rc;
+DIR *pDir = 0;
+
+ errno = 0;
+
+ if (!szPath)
+ errno = EFAULT;
+
+ if ((!errno) && ('\0' == szPath[0]))
+ errno = ENOTDIR;
+
+ // Determine if the given path really is a directory
+
+ if (!errno)
+ if (0 == MultiByteToWideChar (CP_UTF8, 0, (LPCSTR)szPath, -1, (LPWSTR)wpath, sizeof(wpath)))
+ errno = EFAULT;
+
+ if ((!errno) && ((rc = GetFileAttributesW(wpath)) == -1))
+ errno = ENOENT;
+
+ if ((!errno) && (!(rc & FILE_ATTRIBUTE_DIRECTORY)))
+ // Error. Entry exists but not a directory. */
+ errno = ENOTDIR;
+
+ if (!errno)
+ {
+ // Allocate enough memory to store DIR structure, plus
+ // the complete directory path originally supplied.
+ pDir = (DIR *)malloc(sizeof(DIR) + strlen(szPath) + strlen("\\") + strlen ("*"));
+
+ if (!pDir)
+ {
+ // Error - out of memory
+ errno = ENOMEM;
+ }
+ }
+
+ if (!errno)
+ {
+ // Create the search expression
+ strcpy(pDir->dd_name, szPath);
+
+ // Add a backslash if the path doesn't already end with one
+ if (pDir->dd_name[0] != '\0' &&
+ pDir->dd_name[strlen(pDir->dd_name) - 1] != '/' &&
+ pDir->dd_name[strlen(pDir->dd_name) - 1] != '\\')
+ {
+ strcat (pDir->dd_name, "\\");
+ }
+
+ // Add the search pattern
+ strcat(pDir->dd_name, "*");
+
+ // Initialize handle to -1 so that a premature closedir()
+ // doesn't try to call _findclose() on it.
+ pDir->dd_handle = (-1);
+
+ // Initialize the status
+ pDir->dd_stat = 0;
+
+ // Initialize the dirent structure. 'ino' and 'reclen' are invalid under Win32
+ // and 'name' simply points at the appropriate part of the findfirst_t struct.
+ pDir->dd_dir.d_ino = 0;
+ pDir->dd_dir.d_reclen = 0;
+ pDir->dd_dir.d_namlen = 0;
+ strcpy(pDir->dd_dir.d_name, pDir->dd_dta.name);
+
+ return (pDir); // Succeeded
+ }
+
+ if (pDir)
+ free (pDir);
+ return (DIR *) 0; // Failed
+}
+
+
+//***************************************************************
+//
+// readdir()
+//
+// Return a pointer to a dirent struct, filled with information
+// about the next entry in the directory.
+//
+// Returns:
+//
+// On Success: A pointer to the supplied DIR's 'dirent' struct
+// On Failure: NULL
+//
+PBD_API struct dirent* PBD_APICALLTYPE
+readdir (DIR* pDir)
+{
+int old_errno = 0;
+errno = 0;
+
+ // Check for valid DIR struct
+ if (!pDir)
+ errno = EFAULT;
+
+ if ((strcmp(pDir->dd_dir.d_name, pDir->dd_dta.name)) && (!errno))
+ // The structure does not seem to be set up correctly
+ errno = EINVAL;
+ else
+ {
+ if (pDir->dd_stat < 0)
+ {
+ // We have already returned all files in this directory
+ // (or the structure has an invalid dd_stat).
+ return (struct dirent *)0;
+ }
+ else if (pDir->dd_stat == 0)
+ {
+ // We haven't started the search yet.
+ // Start the search
+ pDir->dd_handle = _findfirst (Glib::locale_from_utf8(pDir->dd_name).c_str(), &(pDir->dd_dta));
+
+ if (pDir->dd_handle == -1)
+ // The directory is empty
+ pDir->dd_stat = -1;
+ else
+ pDir->dd_stat = 1;
+ }
+ else
+ {
+ // Do not return ENOENT on last file in directory
+ old_errno = errno;
+
+ // Get the next search entry
+ if (_findnext (pDir->dd_handle, &(pDir->dd_dta)))
+ {
+ // We are off the end or otherwise error
+ errno = old_errno;
+ _findclose (pDir->dd_handle);
+ pDir->dd_handle = -1;
+ pDir->dd_stat = -1;
+ }
+ else
+ // Update to indicate the correct status number
+ pDir->dd_stat++;
+ }
+
+ if (pDir->dd_stat > 0)
+ {
+ // We successfully got an entry. Details about the file are
+ // already appropriately filled in except for the length of
+ // file name.
+ strcpy(pDir->dd_dir.d_name, pDir->dd_dta.name);
+ pDir->dd_dir.d_namlen = strlen (pDir->dd_dir.d_name);
+ return (&pDir->dd_dir); // Succeeded
+ }
+ }
+
+ return (struct dirent *) 0; // Failed
+}
+
+
+//***************************************************************
+//
+// closedir()
+//
+// Frees the resources allocated by opendir().
+//
+// Returns:
+//
+// On Success: 0
+// On Failure: -1
+//
+PBD_API int PBD_APICALLTYPE
+closedir (DIR *pDir)
+{
+int rc = 0;
+
+ errno = 0;
+
+ if (!pDir)
+ errno = EFAULT;
+ else
+ {
+ if ((-1) != pDir->dd_handle)
+ rc = _findclose (pDir->dd_handle);
+
+ // Free the DIR structure
+ free (pDir);
+
+ return rc; // Succeeded
+ }
+
+ return (-1); // Failed
+}
+
+//***************************************************************
+//
+// mkstemp()
+//
+// Emulates Linux mkstemp() using Win32 _mktemp() and _open() etc.
+//
+// Returns:
+//
+// On Success: A file descriptor for the opened file.
+// On Failure: (-1)
+//
+PBD_API int PBD_APICALLTYPE
+mkstemp (char *template_name)
+{
+int ret = (-1);
+char *szFileName;
+char szTempPath[PATH_MAX+100]; // Just ensure we have plenty of buffer space
+
+ if (NULL != (szFileName = _mktemp(template_name)))
+ {
+ if (0 != ::GetTempPathA(sizeof(szTempPath), szTempPath))
+ {
+ strcat(szTempPath, szFileName);
+ ret = _open(szTempPath, (_O_CREAT|_O_BINARY|_O_TEMPORARY|_O_RDWR|_O_TRUNC), _S_IWRITE);
+ }
+ }
+
+ return (ret);
+}
+
+
+//***************************************************************
+//
+// ntfs_link()
+//
+// Emulates Linux link() using Win32 CreateHardLink()(NTFS only).
+//
+// Returns:
+//
+// On Success: Non-zero.
+// On Failure: Zero (call 'GetLastError()' to retrieve info)
+//
+PBD_API int PBD_APICALLTYPE
+ntfs_link (const char *existing_filepath, const char *link_filepath)
+{
+int ret = 1; // 'ERROR_INVALID_FUNCTION'
+bool bValidPath = false;
+
+ // Make sure we've been sent a valid input string
+ if (existing_filepath && link_filepath)
+ {
+ std::string strRoot = existing_filepath;
+
+ if ((1 < strRoot.length()) && ('\\' == existing_filepath[0]) && ('\\' == existing_filepath[1]))
+ {
+ int slashcnt = 0;
+
+ // We've been sent a network path. Convert backslashes to forward slashes temporarily.
+ std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_backslash);
+
+ // Now, if there are less than four slashes, add a fourth one or abort
+ std::string::iterator iter = strRoot.begin();
+ while ((slashcnt < 4) && (iter != strRoot.end()))
+ {
+ if ('/' == (*iter))
+ slashcnt++;
+
+ ++iter;
+ }
+
+ if (slashcnt > 2)
+ {
+ // If only 3 slashes were counted, add a trailing slash
+ if (slashcnt == 3)
+ strRoot += '/';
+
+ // Now find the position of the fourth slash
+ iter = strRoot.begin();
+ int charcnt = 0;
+ for (slashcnt=0; slashcnt<4;)
+ {
+ charcnt++;
+
+ if ('/' == (*iter))
+ slashcnt++;
+
+ if (++iter == strRoot.end())
+ break;
+ }
+
+ strRoot.resize(charcnt);
+ bValidPath = true;
+ }
+ }
+ else
+ {
+ // Assume a standard Windows style path
+ if (1 < strRoot.length() && (':' == existing_filepath[1]))
+ {
+ // Convert backslashes to forward slashes temporarily.
+ std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_backslash);
+
+ if (2 == strRoot.length())
+ strRoot += '/';
+
+ if ('/' == strRoot[2])
+ {
+ strRoot.resize(3);
+ bValidPath = true;
+ }
+ }
+ }
+
+ if (bValidPath)
+ {
+ char szFileSystemType[_MAX_PATH+1];
+
+ // Restore the original backslashes
+ std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_forwardslash);
+
+ // Windows only supports hard links for the NTFS filing
+ // system, so let's make sure that's what we're using!!
+ if (::GetVolumeInformationA(strRoot.c_str(), NULL, 0, NULL, NULL, NULL, szFileSystemType, _MAX_PATH+1))
+ {
+ std::string strRootFileSystemType = szFileSystemType;
+ std::transform(strRootFileSystemType.begin(), strRootFileSystemType.end(), strRootFileSystemType.begin(), ::toupper);
+#if (_WIN32_WINNT >= 0x0500)
+ if (0 == strRootFileSystemType.compare("NTFS"))
+ {
+ if (TestForMinimumSpecOS()) // Hard links were only available from Win2K onwards
+ if (0 == CreateHardLinkA(link_filepath, existing_filepath, NULL))
+ { // Note that the above API call cannot create a link to a directory, so
+ // should we also be checking that the supplied path was actually a file?
+ ret = GetLastError();
+ }
+ else
+ SetLastError(ret = 0); // 'NO_ERROR'
+ }
+ else
+ {
+ ret = 4300; // 'ERROR_INVALID_MEDIA'
+ }
+#endif
+ }
+ }
+ else
+ ret = 123; // 'ERROR_INVALID_NAME'
+ }
+ else
+ ret = 161; // 'ERROR_BAD_PATHNAME'
+
+ if (ret)
+ {
+ SetLastError(ret);
+ return (-1);
+ }
+ else
+ return (0);
+}
+
+
+//***************************************************************
+//
+// ntfs_unlink()
+//
+// Emulates Linux unlink() using Win32 DeleteFile()(NTFS only).
+//
+// Returns:
+//
+// On Success: Non-zero.
+// On Failure: Zero (call 'GetLastError()' to retrieve info)
+//
+PBD_API int PBD_APICALLTYPE
+ntfs_unlink (const char *link_filepath)
+{
+int ret = 1; // 'ERROR_INVALID_FUNCTION'
+bool bValidPath = false;
+
+ // Make sure we've been sent a valid input string
+ if (link_filepath)
+ {
+ std::string strRoot = link_filepath;
+
+ if ((1 < strRoot.length()) && ('\\' == link_filepath[0]) && ('\\' == link_filepath[1]))
+ {
+ int slashcnt = 0;
+
+ // We've been sent a network path. Convert backslashes to forward slashes temporarily.
+ std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_backslash);
+
+ // Now, if there are less than four slashes, add a fourth one or abort
+ std::string::iterator iter = strRoot.begin();
+ while ((slashcnt < 4) && (iter != strRoot.end()))
+ {
+ if ('/' == (*iter))
+ slashcnt++;
+
+ ++iter;
+ }
+
+ if (slashcnt > 2)
+ {
+ // If only 3 slashes were counted, add a trailing slash
+ if (slashcnt == 3)
+ strRoot += '/';
+
+ // Now find the position of the fourth slash
+ iter = strRoot.begin();
+ int charcnt = 0;
+ for (slashcnt=0; slashcnt<4;)
+ {
+ charcnt++;
+
+ if ('/' == (*iter))
+ slashcnt++;
+
+ if (++iter == strRoot.end())
+ break;
+ }
+
+ strRoot.resize(charcnt);
+ bValidPath = true;
+ }
+ }
+ else
+ {
+ // Assume a standard Windows style path
+ if (1 < strRoot.length() && (':' == link_filepath[1]))
+ {
+ // Convert backslashes to forward slashes temporarily.
+ std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_backslash);
+
+ if (2 == strRoot.length())
+ strRoot += '/';
+
+ if ('/' == strRoot[2])
+ {
+ strRoot.resize(3);
+ bValidPath = true;
+ }
+ }
+ }
+
+ if (bValidPath)
+ {
+ char szFileSystemType[_MAX_PATH+1];
+
+ // Restore the original backslashes
+ std::transform(strRoot.begin(), strRoot.end(), strRoot.begin(), invert_forwardslash);
+
+ // Windows only supports hard links for the NTFS filing
+ // system, so let's make sure that's what we're using!!
+ if (::GetVolumeInformationA(strRoot.c_str(), NULL, 0, NULL, NULL, NULL, szFileSystemType, _MAX_PATH+1))
+ {
+ std::string strRootFileSystemType = szFileSystemType;
+ std::transform(strRootFileSystemType.begin(), strRootFileSystemType.end(), strRootFileSystemType.begin(), ::toupper);
+#if (_WIN32_WINNT >= 0x0500)
+ if (0 == strRootFileSystemType.compare("NTFS"))
+ if (TestForMinimumSpecOS()) // Hard links were only available from Win2K onwards
+ if (0 == DeleteFileA(link_filepath))
+ ret = GetLastError();
+ else
+ ret = 0; // 'NO_ERROR'
+#endif
+ }
+ }
+ else
+ ret = 123; // 'ERROR_INVALID_NAME'
+ }
+ else
+ ret = 161; // 'ERROR_BAD_PATHNAME'
+
+ if (ret)
+ {
+ SetLastError(ret);
+ return (-1);
+ }
+ else
+ return (0);
+}
+
+} // namespace PBD
+
+
+//***************************************************************
+//
+// dlopen()
+//
+// Emulates POSIX dlopen() using Win32 LoadLibrary().
+//
+// Returns:
+//
+// On Success: A handle to the opened DLL
+// On Failure: NULL
+//
+PBD_API void* PBD_APICALLTYPE
+dlopen (const char *file_name, int mode)
+{
+ // Note that 'mode' is ignored in Win32
+ return(::LoadLibraryA(Glib::locale_from_utf8(file_name).c_str()));
+}
+
+
+//***************************************************************
+//
+// dlclose()
+//
+// Emulates POSIX dlclose() using Win32 FreeLibrary().
+//
+// Returns:
+//
+// On Success: A non-zero number
+// On Failure: 0
+//
+PBD_API int PBD_APICALLTYPE
+dlclose (void *handle)
+{
+ return (::FreeLibrary((HMODULE)handle));
+}
+
+
+//***************************************************************
+//
+// dlsym()
+//
+// Emulates POSIX dlsym() using Win32 GetProcAddress().
+//
+// Returns:
+//
+// On Success: A pointer to the found function or symbol
+// On Failure: NULL
+//
+PBD_API void* PBD_APICALLTYPE
+dlsym (void *handle, const char *symbol_name)
+{
+ // First test for RTLD_DEFAULT and RTLD_NEXT
+ if ((handle == 0/*RTLD_DEFAULT*/) || (handle == ((void *) -1L)/*RTLD_NEXT*/))
+ {
+ return 0; // Not yet supported for Win32
+ }
+ else
+ return (::GetProcAddress((HMODULE)handle, symbol_name));
+}
+
+#define LOCAL_ERROR_BUF_SIZE 1024
+static char szLastWinError[LOCAL_ERROR_BUF_SIZE];
+//***************************************************************
+//
+// dlerror()
+//
+// Emulates POSIX dlerror() using Win32 GetLastError().
+//
+// Returns:
+//
+// On Success: The translated message corresponding to the
+// last error
+// On Failure: NULL (if the last error was ERROR_SUCCESS)
+//
+PBD_API char* PBD_APICALLTYPE
+dlerror ()
+{
+ DWORD dwLastErrorId = GetLastError();
+ if (ERROR_SUCCESS == dwLastErrorId)
+ return 0;
+ else
+ {
+ if (0 == FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dwLastErrorId,
+ 0,
+ szLastWinError,
+ LOCAL_ERROR_BUF_SIZE,
+ 0))
+ {
+ sprintf(szLastWinError, "Could not decipher the previous error message");
+ }
+
+ // POSIX dlerror() seems to reset the
+ // error system, so emulate that here
+ SetLastError(ERROR_SUCCESS);
+ }
+
+ return(szLastWinError);
+}
+
+#endif // COMPILER_MSVC
--- /dev/null
+/*
+ Copyright (C) 2009 John Emmas
+
+ 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 COMPILER_MSVC
+
+//#include <glib/gtimer.h>
+#include "pbd/msvc_pbd.h"
+
+#ifndef _DWORD_DEFINED
+#define _DWORD_DEFINED
+typedef unsigned long DWORD;
+#endif // !_DWORD_DEFINED
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * Note that this entire strategy failed to work, at least for pipes. It turned *
+ * out that Windows 'tell()' always returns 0 when used on a pipe. This strategy *
+ * is now deprecated, having been replaced by a new pipe-like object, which I've *
+ * called 'PBD::pipex'. This polling functionality is included here mostly so *
+ * that Ardour will build and launch under Windows. However, any module that *
+ * relies on polling a pipe will eventually need to use the new pipex object. *
+ * This code will allow it to compile and link successfully, although it won't *
+ * poll successfully at run time. Having said that, these functions might well *
+ * work for ports and/or other machanisms that get represented by a file handle. *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+int poll_input (struct pollfd *fds, nfds_t nfds, int& elapsed_time, int timeout)
+{
+DWORD dwOldTickCount,
+ dwNewTickCount = GetTickCount();
+bool input = false,
+ error = false;
+int ret = 0;
+
+ if (NULL != fds)
+ {
+ nfds_t loop;
+ short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND);
+
+ errno = NO_ERROR;
+
+ do
+ {
+ dwOldTickCount = dwNewTickCount;
+
+ for (loop=0; loop<nfds; loop++)
+ fds[loop].revents = 0;
+
+ for (loop=0; (loop<nfds && !error); loop++)
+ {
+ if (!(fds[loop].events & ev_mask))
+ {
+ long pos = _tell(fds[loop].fd);
+
+ if (0 > pos)
+ {
+ // An error occured ('errno' should have been set by '_tell()')
+ ret = (-1);
+ fds[loop].revents = POLLERR;
+ if (fds[loop].events & POLLRDNORM)
+ fds[loop].revents |= POLLRDNORM;
+ if (fds[loop].events & POLLRDBAND)
+ fds[loop].revents |= POLLRDBAND;
+ if (fds[loop].events & POLLPRI)
+ fds[loop].revents |= POLLPRI;
+
+ // Do we want to abort on error?
+ if (fds[loop].events & POLLERR)
+ error = true;
+ }
+ else if (pos > 0)
+ {
+ // Input characters were found for this fd
+ ret += 1;
+ if (fds[loop].events & POLLRDNORM)
+ fds[loop].revents |= POLLRDNORM;
+ if (fds[loop].events & POLLRDBAND)
+ fds[loop].revents |= POLLRDBAND;
+ if (fds[loop].events & POLLPRI)
+ fds[loop].revents |= POLLPRI;
+
+ // Do we want to abort on input?
+ if ((fds[loop].events & POLLIN) ||
+ (fds[loop].events & POLLPRI) ||
+ (fds[loop].events & POLLRDNORM) ||
+ (fds[loop].events & POLLRDBAND))
+ input = true;
+ }
+ }
+ }
+
+ if (input)
+ break;
+
+ dwNewTickCount = GetTickCount();
+ elapsed_time += (dwNewTickCount-dwOldTickCount);
+ // Note that the above will wrap round if the user leaves
+ // his computer powered up for more than about 50 days!
+
+ // Sleep briefly because GetTickCount() only has an accuracy of 10mS
+ Sleep(10); // For some reason 'g_usleep()' craps over everything here. Different 'C' runtimes???
+
+ } while ((!error) && ((timeout == (-1)) || (elapsed_time < timeout)));
+ }
+ else
+ {
+ errno = ERROR_BAD_ARGUMENTS;
+ ret = (-1);
+ }
+
+ return (ret);
+}
+
+int poll_output (struct pollfd *fds, nfds_t nfds, int& elapsed_time, int timeout)
+{
+int ret = 0; // This functionality is not yet implemented
+
+ if (NULL != fds)
+ {
+ // Just flag whichever pollfd was specified for writing
+ short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND);
+
+ errno = NO_ERROR;
+ elapsed_time = 0;
+
+ for (nfds_t loop=0; loop<nfds; loop++)
+ {
+ if (fds[loop].events & ev_mask)
+ {
+ fds[loop].revents = POLLNVAL;
+ errno = ERROR_INVALID_ACCESS;
+ ret = (-1);
+ }
+ }
+ }
+ else
+ {
+ errno = ERROR_BAD_ARGUMENTS;
+ ret = (-1);
+ }
+
+ return (ret);
+}
+
+//***************************************************************
+//
+// poll()
+//
+// Emulates POSIX poll() using Win32 _tell().
+//
+// Returns:
+//
+// On Success: A positive integer indicating the total number
+// of file descriptors that were available for
+// writing or had data available for reading.
+// On Failure: -1 (the actual error is saved in 'errno').
+//
+PBD_API int PBD_APICALLTYPE
+poll (struct pollfd *fds, nfds_t nfds, int timeout)
+{
+int elapsed_time = 0;
+int ret = (-1);
+
+ // Note that this functionality is not fully implemented.
+ // At the time of writing, Ardour seems only to poll on
+ // read pipes. Therefore return an error if any write
+ // pipe seems to have been specified or if too many file
+ // descriptors were passed.
+ short ev_mask = (POLLOUT|POLLWRNORM|POLLWRBAND);
+
+ if ((nfds > OPEN_MAX) || (nfds > NPOLLFILE))
+ {
+ errno = ERROR_TOO_MANY_OPEN_FILES;
+ }
+ else
+ {
+ ret = 0;
+
+ for (nfds_t loop=0; loop<nfds; loop++)
+ {
+ if (fds[loop].events & ev_mask)
+ {
+ ret = poll_output(fds, nfds, elapsed_time, timeout);
+ break;
+ }
+ }
+
+ if (0 == ret)
+ {
+ // Poll for input
+ ret = poll_input(fds, nfds, elapsed_time, timeout);
+ }
+ }
+
+ return (ret);
+}
+
+#endif //COMPILER_MSVC
*/
#include <vector>
-#include <climits>
#include <iostream>
+#include <climits>
+#include <cerrno>
+#include <cstdlib>
#include <regex.h>
using std::string;
using std::vector;
+string
+PBD::canonical_path (const std::string& path)
+{
+#ifdef COMPILER_MINGW
+ return path;
+#else
+ char buf[PATH_MAX+1];
+
+ if (!realpath (path.c_str(), buf) && (errno != ENOENT)) {
+ return path;
+ }
+
+ return string (buf);
+#endif
+}
+
string
PBD::path_expand (string path)
{
/* canonicalize */
- char buf[PATH_MAX+1];
-
- if (realpath (path.c_str(), buf)) {
- return buf;
- } else {
- return string();
- }
+ return canonical_path (path);
}
string
$Id$
*/
+#ifdef COMPILER_MSVC
+#include <stdlib.h>
+#include <stdio.h>
+using PBD::readdir;
+using PBD::opendir;
+using PBD::closedir;
+#else
+#include <dirent.h>
#include <cstdlib>
#include <cstdio>
+#endif
#include <cstring>
#include <vector>
-#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "i18n.h"
+#ifdef COMPILER_MSVC
+#include <ardourext/misc.h> // Needed for 'DECLARE_DEFAULT_COMPARISONS'. Objects in an STL container can be
+ // searched and sorted. Thus, when instantiating the container, MSVC complains
+ // if the type of object being contained has no appropriate comparison operators
+ // defined (specifically, if operators '<' and '==' are undefined). This seems
+ // to be the case with ptw32 'pthread_t' which is a simple struct.
+DECLARE_DEFAULT_COMPARISONS(pthread_t)
+#endif
+
using namespace std;
template<typename RequestBuffer> void
return 0;
}
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated per-thread request of type %2, caller %3\n", name(), rt, pthread_self()));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated per-thread request of type %2, caller %3\n", name(), rt, pthread_name()));
vec.buf[0]->type = rt;
vec.buf[0]->valid = true;
* are not at work.
*/
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated normal heap request of type %2, caller %3\n", name(), rt, pthread_self()));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1: allocated normal heap request of type %2, caller %3\n", name(), rt, pthread_name()));
RequestObject* req = new RequestObject;
req->type = rt;
for (i = request_buffers.begin(); i != request_buffers.end(); ) {
if ((*i).second->dead) {
DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 deleting dead per-thread request buffer for %3 @ %4\n",
- name(), pthread_self(), i->first, i->second));
+ name(), pthread_name(), i->second));
delete (*i).second;
RequestBufferMapIterator tmp = i;
++tmp;
request_buffer_map_lock.lock ();
if (!req->valid) {
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 handling invalid heap request, type %3, deleting\n", name(), pthread_self(), req->type));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 handling invalid heap request, type %3, deleting\n", name(), pthread_name(), req->type));
delete req;
request_buffer_map_lock.unlock ();
continue;
*/
if (req->invalidation) {
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 remove request from its invalidation list\n", name(), pthread_self()));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 remove request from its invalidation list\n", name(), pthread_name()));
/* after this call, if the object referenced by the
* invalidation record is deleted, it will no longer
lm.release ();
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 execute request type %3\n", name(), pthread_self(), req->type));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 execute request type %3\n", name(), pthread_name(), req->type));
/* and lets do it ... this is a virtual call so that each
* specific type of UI can have its own set of requests without
do_request (req);
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 delete heap request type %3\n", name(), pthread_self(), req->type));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 delete heap request type %3\n", name(), pthread_name(), req->type));
delete req;
/* re-acquire the list lock so that we check again */
/* the thread that runs this UI's event loop is sending itself
a request: we dispatch it immediately and inline.
*/
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 direct dispatch of request type %3\n", name(), pthread_self(), req->type));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 direct dispatch of request type %3\n", name(), pthread_name(), req->type));
do_request (req);
} else {
RequestBuffer* rbuf = per_thread_request_buffer.get ();
if (rbuf != 0) {
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 send per-thread request type %3\n", name(), pthread_self(), req->type));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 send per-thread request type %3\n", name(), pthread_name(), req->type));
rbuf->increment_write_ptr (1);
} else {
/* no per-thread buffer, so just use a list with a lock so that it remains
single-reader/single-writer semantics
*/
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 send heap request type %3\n", name(), pthread_self(), req->type));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 send heap request type %3\n", name(), pthread_name(), req->type));
Glib::Threads::Mutex::Lock lm (request_list_lock);
request_list.push_back (req);
}
at the per-thread and generic request lists.
*/
- request_channel.wakeup ();
+ signal_new_request ();
}
}
AbstractUI<RequestObject>::call_slot (InvalidationRecord* invalidation, const boost::function<void()>& f)
{
if (caller_is_self()) {
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 direct dispatch of call slot via functor @ %3, invalidation %4\n", name(), pthread_self(), &f, invalidation));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 direct dispatch of call slot via functor @ %3, invalidation %4\n", name(), pthread_name(), &f, invalidation));
f ();
return;
}
return;
}
- DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 queue call-slot using functor @ %3, invalidation %4\n", name(), pthread_self(), &f, invalidation));
+ DEBUG_TRACE (PBD::DEBUG::AbstractUI, string_compose ("%1/%2 queue call-slot using functor @ %3, invalidation %4\n", name(), pthread_name(), &f, invalidation));
/* copy semantics: copy the functor into the request object */
, 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;
--- /dev/null
+/*
+ Copyright (C) 2010 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 PBD_ATOMIC_COUNTER_H
+#define PBD_ATOMIC_COUNTER_H
+
+#include <glib.h>
+
+namespace PBD {
+
+class atomic_counter
+{
+ /**
+ * Prevent copying and assignment
+ */
+ atomic_counter (const atomic_counter&);
+ atomic_counter& operator= (const atomic_counter&);
+
+public:
+
+ atomic_counter (gint value = 0)
+ :
+ m_value(value)
+ { }
+
+ gint get() const
+ {
+ return g_atomic_int_get (&m_value);
+ }
+
+ void set (gint new_value)
+ {
+ g_atomic_int_set (&m_value, new_value);
+ }
+
+ void increment ()
+ {
+ g_atomic_int_inc (&m_value);
+ }
+
+ void operator++ ()
+ {
+ increment ();
+ }
+
+ bool decrement_and_test ()
+ {
+ return g_atomic_int_dec_and_test (&m_value);
+ }
+
+ bool operator-- ()
+ {
+ return decrement_and_test ();
+ }
+
+ bool compare_and_exchange (gint old_value, gint new_value)
+ {
+ return g_atomic_int_compare_and_exchange
+ (
+ &m_value,
+ old_value,
+ new_value
+ );
+ }
+
+ /**
+ * convenience method, \see compare_and_exchange
+ */
+ bool cas (gint old_value, gint new_value)
+ {
+ return compare_and_exchange (old_value, new_value);
+ }
+
+private:
+
+ // Has to be mutable when using the apple version of gcc.
+ mutable volatile gint m_value;
+
+};
+
+} // namespace PBD
+
+#endif // PBD_ATOMIC_COUNTER_H
void quit ();
protected:
- CrossThreadChannel request_channel;
bool _ok;
Glib::RefPtr<Glib::MainLoop> _main_loop;
- Glib::Threads::Thread* run_loop_thread;
+ Glib::RefPtr<Glib::MainContext> m_context;
+ Glib::Threads::Thread* run_loop_thread;
Glib::Threads::Mutex _run_lock;
- Glib::Threads::Cond _running;
+ Glib::Threads::Cond _running;
/* this signals _running from within the event loop,
from an idle callback
virtual void thread_init () {};
+#ifdef PLATFORM_WINDOWS
+ static gboolean _request_handler (gpointer);
+ bool request_handler ();
+#else
/** Called when there input ready on the request_channel
*/
bool request_handler (Glib::IOCondition);
+#endif
+
+ void signal_new_request ();
+ void attach_request_source ();
/** Derived UI objects must implement this method,
* which will be called whenever there are requests
private:
std::string _name;
BaseUI* base_ui_instance;
+
+#ifndef PLATFORM_WINDOWS
+ CrossThreadChannel request_channel;
+#endif
static uint64_t rt_bit;
extern uint64_t Pool;
extern uint64_t EventLoop;
extern uint64_t AbstractUI;
+ extern uint64_t FileUtils;
}
}
--- /dev/null
+/*
+ Copyright (C) 2009 John Emmas
+
+ 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 __platform_fallback_folders_h__
+#define __platform_fallback_folders_h__
+
+#include <pbd/msvc_pbd.h>
+#include <glib/gtypes.h>
+
+#ifdef PLATFORM_WINDOWS // Would not be relevant for Cygwin!!
+ PBD_API gchar* PBD_APICALLTYPE get_win_special_folder (int csidl);
+#endif
+
+namespace PBD {
+
+ typedef enum fallback_folder_t {
+ FOLDER_LOCALE,
+ FOLDER_GTK,
+ FOLDER_CONFIG,
+ FOLDER_ARDOUR,
+ FOLDER_MODULE,
+ FOLDER_DATA,
+ FOLDER_ICONS,
+ FOLDER_PIXMAPS,
+ FOLDER_CONTROL_SURFACES,
+ FOLDER_VAMP,
+ FOLDER_LADSPA,
+ FOLDER_VST,
+ FOLDER_BUNDLED_LV2,
+ FALLBACK_FOLDER_MAX
+ };
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ PBD_API G_CONST_RETURN gchar* PBD_APICALLTYPE get_platform_fallback_folder (PBD::fallback_folder_t index);
+ PBD_API G_CONST_RETURN gchar* G_CONST_RETURN * PBD_APICALLTYPE alloc_platform_fallback_folders ();
+ PBD_API void PBD_APICALLTYPE free_platform_fallback_folders ();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+} // namespace PBD
+
+#endif /* __platform_fallback_folders_h__ */
--- /dev/null
+/*
+ Copyright (C) 2013 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 __libpbd_ffs_h__
+#define __libpbd_ffs_h__
+
+namespace PBD {
+ int ffs(int x);
+}
+
+#endif /* __libpbd_ffs_h__ */
std::vector<std::string>& result);
/**
- * Takes a SearchPath and puts a list of all the files in the search path
+ * Takes a Searchpath and puts a list of all the files in the search path
* that match pattern into the result vector.
*
- * @param search_path A SearchPath
+ * @param search_path A Searchpath
* @param pattern A Glib::PatternSpec used to match the files
* @param result A vector in which to place the resulting matches.
*/
void
-find_matching_files_in_search_path (const SearchPath& search_path,
+find_matching_files_in_search_path (const Searchpath& search_path,
const Glib::PatternSpec& pattern,
std::vector<std::string>& result);
* @return true If file is found within the search path.
*/
bool
-find_file_in_search_path (const SearchPath& search_path,
+find_file_in_search_path (const Searchpath& search_path,
const std::string& filename,
std::string& result);
#ifndef __libpbd__floating_h__
#define __libpbd__floating_h__
+#include <stdint.h>
+
#include <cmath>
namespace PBD {
--- /dev/null
+/*
+ Copyright (C) 2010 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 PBD_GLIB_SEMAPHORE_H
+#define PBD_GLIB_SEMAPHORE_H
+
+#include <glibmm/threads.h>
+
+#include "atomic_counter.h"
+
+namespace PBD {
+
+class GlibSemaphore
+{
+
+ // prevent copying and assignment
+ GlibSemaphore(const GlibSemaphore& sema);
+ GlibSemaphore& operator= (const GlibSemaphore& sema);
+
+public:
+
+ GlibSemaphore (gint initial_val = 1);
+
+ void wait ();
+
+ bool try_wait ();
+
+ void post ();
+
+private:
+
+ atomic_counter m_counter;
+ Glib::Threads::Cond m_cond;
+ Glib::Threads::Mutex m_mutex;
+
+};
+
+} // namespace PBD
+
+#endif // PBD_SEMAPHORE_H
--- /dev/null
+/*
+ Copyright (C) 1999-2010 Paul Davis
+
+ 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 __pbd_localeguard_h__
+#define __pbd_localeguard_h__
+
+#include <string>
+
+namespace PBD {
+
+struct LocaleGuard {
+ LocaleGuard (const char*);
+ ~LocaleGuard ();
+ const char* old;
+
+ /* JE - temporary !!!! */static std::string current;
+};
+
+}; // namespace
+
+#endif /* __pbd_localeguard_h__ */
--- /dev/null
+#ifndef PBD_LOCALTIME_R
+#define PBD_LOCALTIME_R
+#include <time.h>
+
+#ifdef COMPILER_MSVC
+ #define localtime_r( _clock, _result ) \
+ ( *(_result) = *localtime( (_clock) ), \
+ (_result) )
+#else
+ extern struct tm *localtime_r(const time_t *const timep, struct tm *p_tm);
+#endif
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2009 John Emmas
+
+ 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 _msvc_pbd_h_
+#define _msvc_pbd_h_
+
+#ifdef PBD_IS_IN_WIN_STATIC_LIB // #define if your project uses libpbd (under Windows) as a static library
+#define PBD_IS_IN_WINDLL 0
+#endif
+
+#ifndef COMPILER_MSVC
+#include <sys/time.h>
+#else
+#include <ardourext/misc.h>
+#include <ardourext/sys/time.h>
+#endif
+
+#if !defined(PBD_IS_IN_WINDLL)
+ #if defined(COMPILER_MSVC) || defined(COMPILER_MINGW)
+ // If you need '__declspec' compatibility, add extra compilers to the above as necessary
+ #define PBD_IS_IN_WINDLL 1
+ #else
+ #define PBD_IS_IN_WINDLL 0
+ #endif
+#endif
+
+#if PBD_IS_IN_WINDLL && !defined(PBD_API)
+ #if defined(BUILDING_PBD)
+ #define PBD_API __declspec(dllexport)
+ #define PBD_APICALLTYPE __stdcall
+ #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point
+ #define PBD_API __declspec(dllimport)
+ #define PBD_APICALLTYPE __stdcall
+ #else
+ #error "Attempting to define __declspec with an incompatible compiler !"
+ #endif
+#elif !defined(PBD_API)
+ // Other compilers / platforms could be accommodated here
+ #define PBD_API
+ #define PBD_APICALLTYPE
+ #define GETOPT_API
+ #define GETOPT_APICALLTYPE
+#endif
+
+#ifndef GETOPT_API
+ #if defined(BUILDING_GETOPT)
+ #define GETOPT_API __declspec(dllexport)
+ #define GETOPT_APICALLTYPE __cdecl
+ #elif defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW__) || defined(_MINGW32__)
+ #define GETOPT_API __declspec(dllimport)
+ #define GETOPT_APICALLTYPE __cdecl
+ #else
+ #error "Attempting to define __declspec with an incompatible compiler !"
+ #endif
+#endif // GETOPT_API
+
+#ifndef _MAX_PATH
+#define _MAX_PATH 260
+#endif
+#ifndef PATH_MAX
+#define PATH_MAX _MAX_PATH
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+// This function is (hopefully) temporary and is placed here
+// because 'g_usleep()' doesn't seem to work very well for glib-win32
+// JE - let's see if we can do without this now! void pbd_g_usleep (unsigned long microseconds);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#ifndef POLLIN
+#define POLLIN 1
+#define POLLPRI 2
+#define POLLOUT 4
+#define POLLERR 8
+#define POLLHUP 16
+#define POLLNVAL 32
+#define NPOLLFILE 64
+
+#define POLLRDNORM POLLIN
+#define POLLRDBAND POLLIN
+#define POLLWRNORM POLLOUT
+#define POLLWRBAND POLLOUT
+#endif
+
+#ifdef PLATFORM_WINDOWS
+
+#ifndef PBDEXTN_API
+ #if defined(BUILDING_PBDEXTN)
+ #define PBDEXTN_API __declspec(dllexport)
+ #define PBDEXTN_APICALLTYPE __cdecl
+ #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point
+ #define PBDEXTN_API __declspec(dllimport)
+ #define PBDEXTN_APICALLTYPE __cdecl
+ #else
+ #error "Attempting to define __declspec with an incompatible compiler !"
+ #endif
+#endif // PBDEXTN_API
+
+#ifndef CYGIMPORT_API
+ #define CYGIMPORT_API __declspec(dllimport)
+ #define CYGIMPORT_APICALLTYPE __cdecl
+#endif // CYGIMPORT_API
+
+#ifndef __THROW
+#define __THROW throw()
+#endif
+
+#ifndef RTLD_DEFAULT
+#define RTLD_DEFAULT ((void *) 0)
+#define RTLD_NEXT ((void *) -1L)
+#define RTLD_LAZY 0x00001
+#define RTLD_NOW 0x00002
+#define RTLD_BINDING_MASK 0x00003
+#define RTLD_NOLOAD 0x00004
+#define RTLD_GLOBAL 0x00004
+#define RTLD_DEEPBIND 0x00008
+#endif
+
+#ifndef OPEN_MAX
+#define OPEN_MAX 32
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+PBDEXTN_API int PBDEXTN_APICALLTYPE cyginit (unsigned int result);
+PBD_API int PBD_APICALLTYPE dlclose (void *handle) __THROW;
+PBD_API void* PBD_APICALLTYPE dlopen (const char *file_name, int mode) __THROW;
+PBD_API void* PBD_APICALLTYPE dlsym (void *handle, const char *symbol_name) __THROW;
+PBD_API char* PBD_APICALLTYPE dlerror () __THROW;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#ifndef __CYGWIN__
+#include <rpc.h>
+#include <io.h>
+#include <sys/types.h>
+
+typedef int (FAR PBDEXTN_APICALLTYPE *CYGINIT_API)(unsigned int);
+
+#ifndef FILENAME_MAX
+#define FILENAME_MAX (260)
+#endif
+
+#ifndef _SSIZE_T_
+#define _SSIZE_T_
+typedef long _ssize_t;
+
+#ifndef _NO_OLDNAMES
+typedef _ssize_t ssize_t;
+#endif
+#endif /* ! _SSIZE_T_ */
+
+struct dirent
+{
+ long d_ino; // Always zero
+ unsigned short d_reclen; // Always zero
+ unsigned short d_namlen; // Length of name in d_name
+ char d_name[FILENAME_MAX]; // File name
+};
+
+// This is an internal data structure. Do not use it
+// except as an argument to one of the functions below.
+typedef struct
+{
+ // Disk transfer area for this dir
+ struct _finddata_t dd_dta;
+
+ // 'dirent' struct to return from dir (NOTE: this
+ // is not thread safe).
+ struct dirent dd_dir;
+
+ // '_findnext()' handle
+ long dd_handle;
+
+ // Current status of search:
+ // 0 = not started yet (next entry to read is first entry)
+ // -1 = off the end
+ // Otherwise - positive (0 based) index of next entry
+ int dd_stat;
+
+ // Full path for dir with search pattern (struct will be extended)
+ char dd_name[1];
+} DIR;
+
+struct pollfd
+{
+ int fd;
+ short events;
+ short revents;
+};
+
+typedef unsigned int nfds_t;
+
+PBD_API int PBD_APICALLTYPE gettimeofday(struct timeval *__restrict tv, __timezone_ptr_t tz);
+PBD_API ssize_t PBD_APICALLTYPE pread(int handle, void *buf, size_t nbytes, off_t offset);
+PBD_API ssize_t PBD_APICALLTYPE pwrite(int handle, const void *buf, size_t nbytes, off_t offset);
+PBD_API int PBD_APICALLTYPE poll(struct pollfd *fds, nfds_t nfds, int timeout);
+PBD_API double PBD_APICALLTYPE round(double x);
+
+namespace PBD {
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+PBD_API bool PBD_APICALLTYPE TestForMinimumSpecOS(char *revision="currently ignored");
+PBD_API char* PBD_APICALLTYPE realpath (const char *original_path, char resolved_path[_MAX_PATH+1]);
+PBD_API int PBD_APICALLTYPE mkstemp (char *template_name);
+PBD_API int PBD_APICALLTYPE ntfs_link (const char *existing_filepath, const char *link_filepath);
+PBD_API int PBD_APICALLTYPE ntfs_unlink (const char *link_filepath);
+
+// These are used to replicate 'dirent.h' functionality
+PBD_API DIR* PBD_APICALLTYPE opendir (const char *szPath);
+PBD_API struct dirent* PBD_APICALLTYPE readdir (DIR *pDir);
+PBD_API int PBD_APICALLTYPE closedir (DIR *pDir);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+} // namespace PBD
+
+#endif // !__CYGWIN__
+#endif // PLATFORM_WINDOWS
+#endif // _msvc_pbd_h_
#include <string>
namespace PBD {
+ std::string canonical_path (const std::string& path);
std::string path_expand (std::string path);
std::string search_path_expand (std::string path);
}
#include <vector>
#include <string>
+#ifdef COMPILER_MSVC
+#include <ardourext/misc.h>
+#else
#include <regex.h>
+#endif
class PathScanner
#ifndef __pbd_pthread_utils__
#define __pbd_pthread_utils__
+#ifdef COMPILER_MSVC
+#include <ardourext/pthread.h>
+#else
#include <pthread.h>
+#endif
#include <signal.h>
#include <string>
#include <stdint.h>
--- /dev/null
+/*
+ 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>
+
+namespace PBD {
+
+typedef uint64_t rlimit_t;
+
+enum ResourceType {
+ OpenFiles
+};
+
+struct ResourceLimit
+{
+ rlimit_t current_limit;
+ rlimit_t max_limit;
+};
+
+/**
+ * @return true on success, false on error
+ */
+bool
+get_resource_limit (ResourceType resource, ResourceLimit& limit);
+
+/**
+ * @return true on success, false on error
+ */
+bool
+set_resource_limit (ResourceType resource, const ResourceLimit& limit);
+
+
+} // namespace PBD
}
template<class T> void
-RingBuffer<T>::get_read_vector (RingBuffer<T>::rw_vector *vec)
+RingBuffer<T>::get_read_vector (typename RingBuffer<T>::rw_vector *vec)
{
guint free_cnt;
}
template<class T> void
-RingBuffer<T>::get_write_vector (RingBuffer<T>::rw_vector *vec)
+RingBuffer<T>::get_write_vector (typename RingBuffer<T>::rw_vector *vec)
{
guint free_cnt;
}
template<class T> void
-RingBufferNPT<T>::get_read_vector (RingBufferNPT<T>::rw_vector *vec)
+RingBufferNPT<T>::get_read_vector (typename RingBufferNPT<T>::rw_vector *vec)
{
size_t free_cnt;
size_t cnt2;
}
template<class T> void
-RingBufferNPT<T>::get_write_vector (RingBufferNPT<T>::rw_vector *vec)
+RingBufferNPT<T>::get_write_vector (typename RingBufferNPT<T>::rw_vector *vec)
{
size_t free_cnt;
size_t cnt2;
namespace PBD {
/**
- * @class SearchPath
+ * @class Searchpath
*
- * The SearchPath class is a helper class for getting a
+ * The Searchpath class is a helper class for getting a
* vector of paths contained in a search path string where a
* "search path string" contains absolute directory paths
* separated by a colon(:) or a semi-colon(;) on windows.
*
- * The SearchPath class does not test whether the paths exist
+ * The Searchpath class does not test whether the paths exist
* or are directories. It is basically just a container.
*/
-class SearchPath : public std::vector<std::string>
+class Searchpath : public std::vector<std::string>
{
public:
/**
- * Create an empty SearchPath.
+ * Create an empty Searchpath.
*/
- SearchPath ();
+ Searchpath ();
/**
- * Initialize SearchPath from a string where the string contains
+ * Initialize Searchpath from a string where the string contains
* one or more absolute paths to directories which are delimited
* by a path separation character. The path delimeter is a
* colon(:) on unix and a semi-colon(;) on windows.
*
* @param search_path A path string.
*/
- SearchPath (const std::string& search_path);
+ Searchpath (const std::string& search_path);
/**
- * Initialize SearchPath from a vector of paths that may or may
+ * Initialize Searchpath from a vector of paths that may or may
* not exist.
*
* @param paths A vector of paths.
*/
- SearchPath (const std::vector<std::string>& paths);
+ Searchpath (const std::vector<std::string>& paths);
/**
* @return a search path string.
/**
* Add all the directories in path to this.
*/
- SearchPath& operator+= (const SearchPath& spath);
+ Searchpath& operator+= (const Searchpath& spath);
/**
* Add another directory path to the search path.
*/
- SearchPath& operator+= (const std::string& directory_path);
+ Searchpath& operator+= (const std::string& directory_path);
/**
- * Concatenate another SearchPath onto this.
+ * Concatenate another Searchpath onto this.
*/
- SearchPath& operator+ (const SearchPath& other);
+ Searchpath& operator+ (const Searchpath& other);
/**
* Add another path to the search path.
*/
- SearchPath& operator+ (const std::string& directory_path);
+ Searchpath& operator+ (const std::string& directory_path);
/**
* Add a sub-directory to each path in the search path.
* @param subdir The directory name, it should not contain
* any path separating tokens.
*/
- SearchPath& add_subdirectory_to_paths (const std::string& subdir);
+ Searchpath& add_subdirectory_to_paths (const std::string& subdir);
protected:
#ifdef __APPLE__
# include <mach/mach.h>
-#elif defined(_WIN32)
+#elif defined(PLATFORM_WINDOWS)
# include <windows.h>
+#ifndef INFINITE
+#define INFINITE 0xffffffffL
+#endif
#else
# include <semaphore.h>
# include <errno.h>
private:
#if defined(__APPLE__)
semaphore_t _sem; // sem_t is a worthless broken mess on OSX
-#elif defined(_WIN32)
+#elif defined(PLATFORM_WINDOWS)
HANDLE _sem; // types are overrated anyway
#else
sem_t _sem;
return semaphore_timedwait(_sem, zero) == KERN_SUCCESS;
}
-#elif defined(_WIN32)
+#elif defined(PLATFORM_WINDOWS)
inline
Semaphore::Semaphore(unsigned initial)
return WaitForSingleObject(_sem, 0) == WAIT_OBJECT_0;
}
-#else /* !defined(__APPLE__) && !defined(_WIN32) */
+#else /* !defined(__APPLE__) && !defined(PLATFORM_WINDOWS) */
Semaphore::Semaphore(unsigned initial)
{
#ifndef __pbd_semutils_h__
#define __pbd_semutils_h__
+#ifdef PLATFORM_WINDOWS
+#include <windows.h>
+#else
#include <semaphore.h>
+#endif
namespace PBD {
class ProcessSemaphore {
private:
-#ifdef __APPLE__
+#ifdef PLATFORM_WINDOWS
+ HANDLE _sem;
+
+#elif __APPLE__
sem_t* _sem;
sem_t* ptr_to_sem() const { return _sem; }
#else
ProcessSemaphore (const char* name, int val);
~ProcessSemaphore ();
+#ifdef PLATFORM_WINDOWS
+
+ int signal ();
+ int wait ();
+
+#else
int signal () { return sem_post (ptr_to_sem()); }
int wait () { return sem_wait (ptr_to_sem()); }
+#endif
};
}
/* record the change described in our change member */
if (!_changes.added.empty()) {
- for (typename ChangeContainer::iterator i = _changes.added.begin(); i != _changes.added.end(); ++i) {
+ for (typename ChangeContainer::const_iterator i = _changes.added.begin(); i != _changes.added.end(); ++i) {
XMLNode* add_node = new XMLNode ("Add");
child->add_child_nocopy (*add_node);
get_content_as_xml (*i, *add_node);
}
}
if (!_changes.removed.empty()) {
- for (typename ChangeContainer::iterator i = _changes.removed.begin(); i != _changes.removed.end(); ++i) {
+ for (typename ChangeContainer::const_iterator i = _changes.removed.begin(); i != _changes.removed.end(); ++i) {
XMLNode* remove_node = new XMLNode ("Remove");
child->add_child_nocopy (*remove_node);
get_content_as_xml (*i, *remove_node);
with this diff().
*/
- for (typename ChangeContainer::iterator i = a->changes().added.begin(); i != a->changes().added.end(); ++i) {
+ for (typename ChangeContainer::const_iterator i = a->changes().added.begin(); i != a->changes().added.end(); ++i) {
(*i)->DropReferences.connect_same_thread (*cmd, boost::bind (&Destructible::drop_references, cmd));
}
}
--- /dev/null
+/* Copyright (C) 1991-1994,1996-2003,2005,2006,2009
+ Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/time.h>
+
+#ifndef timersub
+# define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+
#include <map>
#include <sigc++/slot.h>
#include <sigc++/bind.h>
+#ifndef COMPILER_MSVC
#include <sys/time.h>
+#else
+#include <ardourext/misc.h>
+#endif
#include "pbd/command.h"
#define __pbd_uuid_h__
#include <string>
-#include <uuid/uuid.h>
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_generators.hpp>
namespace PBD {
-class UUID {
+class UUID : public boost::uuids::uuid {
public:
- UUID () { uuid_generate (id); }
- UUID (UUID const & other) { uuid_copy (id, other.id); }
- UUID (std::string const & str) { uuid_parse (str.c_str(), id); }
-
- UUID& operator= (std::string const & str);
- std::string to_s () const;
-
- bool operator== (UUID const & other) const { return !uuid_compare (id, other.id); }
- bool operator!= (UUID const & other) const { return uuid_compare (id, other.id); }
- bool operator< (UUID const & other) const { return uuid_compare (id, other.id) < 0; }
-
- operator bool() const { return !uuid_is_null (id); }
-
- private:
- uuid_t id;
+ UUID ()
+ : boost::uuids::uuid (boost::uuids::random_generator()()) {}
+ UUID (std::string const & str)
+ : boost::uuids::uuid (boost::uuids::string_generator()(str)) {}
+ explicit UUID (boost::uuids::uuid const& u)
+ : boost::uuids::uuid(u)
+ {}
+
+ operator boost::uuids::uuid() {
+ return static_cast<boost::uuids::uuid&>(*this);
+ }
+
+ operator boost::uuids::uuid() const {
+ return static_cast<boost::uuids::uuid const&>(*this);
+ }
+
+ UUID& operator= (std::string const & str);
+ std::string to_s () const;
+
+ operator bool() const { return !is_nil(); }
};
} // namespace PBD
+++ /dev/null
-/*
- Copyright (C) 2008 Paul Davis
- Author: Sakari Bergen
-
- 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 __pbd_uuid_h__
-#define __pbd_uuid_h__
-
-#include <string>
-#include <boost/uuid/uuid.hpp>
-#include <boost/uuid/uuid_generators.hpp>
-
-namespace PBD {
-
-class UUID : public boost::uuids::uuid {
-
- public:
- UUID ()
- : boost::uuids::uuid (boost::uuids::random_generator()()) {}
- UUID (std::string const & str)
- : boost::uuids::uuid (boost::uuids::string_generator()(str)) {}
-
- explicit UUID (boost::uuids::uuid const& u)
- : boost::uuids::uuid(u)
- {}
-
- operator boost::uuids::uuid() {
- return static_cast<boost::uuids::uuid&>(*this);
- }
-
- operator boost::uuids::uuid() const {
- return static_cast<boost::uuids::uuid const&>(*this);
- }
-
- UUID& operator= (std::string const & str);
- std::string to_s () const;
-
- operator bool() const { return !is_nil(); }
-};
-
-} // namespace PBD
-
-#endif // __pbd_uuid_h__
#include <cassert>
#include "pbd/pool.h"
+#include "pbd/pthread_utils.h"
#include "pbd/error.h"
#include "pbd/debug.h"
#include "pbd/compose.h"
{
CrossThreadPool* p = _key.get();
if (!p) {
- fatal << "programming error: no per-thread pool \"" << _name << "\" for thread " << pthread_self() << endmsg;
+ fatal << "programming error: no per-thread pool \"" << _name << "\" for thread " << pthread_name() << endmsg;
/*NOTREACHED*/
}
return p;
{
void* ptr;
- DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 has %3 pending free entries waiting\n", pthread_self(), name(), pending.read_space()));
+ DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 has %3 pending free entries waiting\n", pthread_name(), name(), pending.read_space()));
while (pending.read (&ptr, 1) == 1) {
- DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 pushes back a pending free list entry before allocating\n", pthread_self(), name()));
+ DEBUG_TRACE (DEBUG::Pool, string_compose ("%1 %2 pushes back a pending free list entry before allocating\n", pthread_name(), name()));
free_list.write (&ptr, 1);
}
return Pool::alloc ();
#include <fst.h>
#endif
+#ifdef COMPILER_MSVC
+DECLARE_DEFAULT_COMPARISONS(pthread_t) // Needed for 'DECLARE_DEFAULT_COMPARISONS'. Objects in an STL container can be
+ // searched and sorted. Thus, when instantiating the container, MSVC complains
+ // if the type of object being contained has no appropriate comparison operators
+ // defined (specifically, if operators '<' and '==' are undefined). This seems
+ // to be the case with ptw32 'pthread_t' which is a simple struct.
+#endif
+
using namespace std;
-typedef std::set<pthread_t> ThreadMap;
+typedef std::list<pthread_t> ThreadMap;
static ThreadMap all_threads;
static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER;
static Glib::Threads::Private<char> thread_name (free);
if ((ret = thread_creator (thread, &default_attr, fake_thread_start, ts)) == 0) {
pthread_mutex_lock (&thread_map_lock);
- all_threads.insert (*thread);
+ all_threads.push_back (*thread);
pthread_mutex_unlock (&thread_map_lock);
}
{
pthread_mutex_lock (&thread_map_lock);
for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ++i) {
- if ((*i) != pthread_self()) {
+ if (!pthread_equal ((*i), pthread_self())) {
pthread_kill ((*i), signum);
}
}
pthread_cancel_all ()
{
pthread_mutex_lock (&thread_map_lock);
+
for (ThreadMap::iterator i = all_threads.begin(); i != all_threads.end(); ) {
ThreadMap::iterator nxt = i;
--- /dev/null
+/*
+ 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 PLATFORM_WINDOWS
+#include <stdio.h>
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+#include "pbd/resource.h"
+
+namespace PBD {
+
+bool
+get_resource_limit (ResourceType resource, ResourceLimit& limit)
+{
+ if (resource == OpenFiles)
+ {
+#ifdef PLATFORM_WINDOWS
+ limit.current_limit = _getmaxstdio();
+ limit.max_limit = 2048;
+ return true;
+#else
+ struct rlimit rl;
+ if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
+ limit.current_limit = rl.rlim_cur;
+ limit.max_limit = rl.rlim_max;
+ return true;
+ }
+#endif
+ }
+
+ return false;
+}
+
+bool
+set_resource_limit (ResourceType resource, const ResourceLimit& limit)
+{
+ if (resource == OpenFiles)
+ {
+#ifdef PLATFORM_WINDOWS
+ // no soft and hard limits on windows
+ rlimit_t new_max = _setmaxstdio(limit.current_limit);
+
+ if (new_max == limit.current_limit) return true;
+#else
+ struct rlimit rl;
+ rl.rlim_cur = limit.current_limit;
+ rl.rlim_max = limit.max_limit;
+ if (setrlimit (RLIMIT_NOFILE, &rl) == 0) {
+ return true;
+ }
+
+#endif
+ }
+
+ return false;
+}
+
+} // namespace PBD
namespace {
-#ifdef WIN32
+#ifdef PLATFORM_WINDOWS
const char * const path_delimiter = ";";
#else
const char * const path_delimiter = ":";
namespace PBD {
-SearchPath::SearchPath ()
+Searchpath::Searchpath ()
{
}
-SearchPath::SearchPath (const string& path)
+Searchpath::Searchpath (const string& path)
{
vector<std::string> tmp;
}
}
-SearchPath::SearchPath (const vector<std::string>& paths)
+Searchpath::Searchpath (const vector<std::string>& paths)
{
add_directories (paths);
}
void
-SearchPath::add_directory (const std::string& directory_path)
+Searchpath::add_directory (const std::string& directory_path)
{
if (!directory_path.empty()) {
push_back(directory_path);
}
void
-SearchPath::add_directories (const vector<std::string>& paths)
+Searchpath::add_directories (const vector<std::string>& paths)
{
for(vector<std::string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
add_directory (*i);
}
const string
-SearchPath::to_string () const
+Searchpath::to_string () const
{
string path;
return path;
}
-SearchPath&
-SearchPath::operator+= (const SearchPath& spath)
+Searchpath&
+Searchpath::operator+= (const Searchpath& spath)
{
insert(end(), spath.begin(), spath.end());
return *this;
}
-SearchPath&
-SearchPath::operator+= (const std::string& directory_path)
+Searchpath&
+Searchpath::operator+= (const std::string& directory_path)
{
add_directory (directory_path);
return *this;
}
-SearchPath&
-SearchPath::operator+ (const std::string& directory_path)
+Searchpath&
+Searchpath::operator+ (const std::string& directory_path)
{
add_directory (directory_path);
return *this;
}
-SearchPath&
-SearchPath::operator+ (const SearchPath& spath)
+Searchpath&
+Searchpath::operator+ (const Searchpath& spath)
{
- // concatenate paths into new SearchPath
+ // concatenate paths into new Searchpath
insert(end(), spath.begin(), spath.end());
return *this;
}
-SearchPath&
-SearchPath::add_subdirectory_to_paths (const string& subdir)
+Searchpath&
+Searchpath::add_subdirectory_to_paths (const string& subdir)
{
for (vector<std::string>::iterator i = begin(); i != end(); ++i) {
// should these new paths just be added to the end of
ProcessSemaphore::ProcessSemaphore (const char* name, int val)
{
-#ifdef __APPLE__
+#ifdef PLATFORM_WINDOWS
+ if ((_sem = CreateSemaphore(NULL, val, 32767, name)) == NULL) {
+ throw failed_constructor ();
+ }
+
+#elif __APPLE__
if ((_sem = sem_open (name, O_CREAT, 0600, val)) == (sem_t*) SEM_FAILED) {
throw failed_constructor ();
}
ProcessSemaphore::~ProcessSemaphore ()
{
-#ifdef __APPLE__
+#ifdef PLATFORM_WINDOWS
+ CloseHandle(_sem);
+#elif __APPLE__
sem_close (ptr_to_sem());
#endif
}
+
+#ifdef PLATFORM_WINDOWS
+
+int
+ProcessSemaphore::signal ()
+{
+ // non-zero on success, opposite to posix
+ return !ReleaseSemaphore(_sem, 1, NULL);
+}
+
+int
+ProcessSemaphore::wait ()
+{
+ DWORD result = 0;
+ result = WaitForSingleObject(_sem, INFINITE);
+ return (result == WAIT_OBJECT_0);
+}
+
+#endif
*/
#include <sys/time.h>
-#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
$Id: stateful.cc 629 2006-06-21 23:01:03Z paul $
*/
+#ifdef COMPILER_MSVC
+#include <io.h> // Microsoft's nearest equivalent to <unistd.h>
+#else
#include <unistd.h>
+#endif
#include <glibmm/fileutils.h>
#include <glibmm/miscutils.h>
void
FilesystemTest::testPathIsWithin ()
{
+#ifndef PLATFORM_WINDOWS
system ("rm -r foo");
CPPUNIT_ASSERT (g_mkdir_with_parents ("foo/bar/baz", 0755) == 0);
CPPUNIT_ASSERT (PBD::path_is_within ("foo/bar", "foo/bar"));
CPPUNIT_ASSERT (PBD::path_is_within ("foo/jim/baz", "frobozz") == false);
+#endif
}
--- /dev/null
+#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());
+
+}
--- /dev/null
+#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;
+};
* in an installed location on windows or by setting an environment variable
* on unix.
*/
-PBD::SearchPath
+PBD::Searchpath
test_search_path ()
{
-#ifdef WIN32
+#ifdef PLATFORM_WINDOWS
std::string wsp(g_win32_get_package_installation_directory_of_module(NULL));
return Glib::build_filename (wsp, "pbd_testdata");
#else
#include "pbd/search_path.h"
-PBD::SearchPath test_search_path ();
+PBD::Searchpath test_search_path ();
#endif
#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;
/* do the right thing if this should not return */
if (does_not_return()) {
+#ifndef PLATFORM_WINDOWS
+// TODO !!!! Commented out temporarily (for Windows)
sigset_t mask;
sigemptyset (&mask);
sigsuspend (&mask);
/*NOTREACHED*/
exit (1);
+/* JE - From what I can tell, the above code suspends
+ * program execution until (any) signal occurs. Not
+ * sure at the moment what this achieves, unless it
+ * provides some time for the user to see the message.
+ */
+#endif
}
}
#include "pbd/uuid.h"
-using namespace PBD;
-
-UUID&
-UUID::operator= (std::string const & str)
+PBD::UUID&
+PBD::UUID::operator= (std::string const & str)
{
- uuid_parse (str.c_str(), id);
+ boost::uuids::string_generator gen;
+ *((boost::uuids::uuid*) this) = gen (str);
return *this;
}
std::string
-UUID::to_s () const
+PBD::UUID::to_s () const
{
- char buf[37];
- uuid_unparse (id, buf);
- return std::string (buf);
+ return std::string ((const char*) data, size());
}
+++ /dev/null
-/*
- Copyright (C) 2008 Paul Davis
- Author: Sakari Bergen
-
- 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 "pbd/uuid.h"
-
-using namespace PBD;
-
-UUID&
-UUID::operator= (std::string const & str)
-{
- boost::uuids::string_generator gen;
- *((boost::uuids::uuid*) this) = gen (str);
- return *this;
-}
-
-std::string
-UUID::to_s () const
-{
- return std::string ((const char*) data, size());
-}
'controllable.cc',
'controllable_descriptor.cc',
'clear_dir.cc',
- 'crossthread.cc',
'cpus.cc',
'debug.cc',
'enumwriter.cc',
'enums.cc',
'epa.cc',
'error.cc',
+ 'ffs.cc',
'file_manager.cc',
'file_utils.cc',
'fpu.cc',
+ 'glib_semaphore.cc',
'id.cc',
'locale_guard.cc',
+ 'localtime_r.cc',
'malign.cc',
'mountpoint.cc',
'openuri.cc',
'property_list.cc',
'pthread_utils.cc',
'receiver.cc',
+ 'resource.cc',
'search_path.cc',
'semutils.cc',
'shortpath.cc',
autowaf.configure(conf)
autowaf.check_pkg(conf, 'libxml-2.0', uselib_store='XML')
autowaf.check_pkg(conf, 'sigc++-2.0', uselib_store='SIGCPP', atleast_version='2.0')
- if sys.platform != 'darwin':
- autowaf.check_pkg(conf, 'uuid', uselib_store='UUID')
conf.check(function_name='getmntent', header_name='mntent.h', define_name='HAVE_GETMNTENT',mandatory=False)
conf.check(header_name='execinfo.h', define_name='HAVE_EXECINFO',mandatory=False)
conf.check(header_name='unistd.h', define_name='HAVE_UNISTD',mandatory=False)
conf.check_cc(function_name='posix_memalign', header_name='stdlib.h', cflags='-D_XOPEN_SOURCE=600', define_name='HAVE_POSIX_MEMALIGN', mandatory=False)
+ conf.check(function_name='localtime_r', header_name='time.h', define_name='HAVE_LOCALTIME_R',mandatory=False)
conf.write_config_header('libpbd-config.h', remove=False)
# Boost headers
autowaf.check_header(conf, 'cxx', 'boost/shared_ptr.hpp')
autowaf.check_header(conf, 'cxx', 'boost/weak_ptr.hpp')
- # autowaf.check_header(conf, 'cxx', 'boost/uuid/uuid.hpp')
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'
testobj.source = '''
test/testrunner.cc
test/xpath.cc
+ test/mutex_test.cc
test/scalar_properties.cc
test/signals_test.cc
test/convert_test.cc
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']
void
XMLTree::debug(FILE* out) const
{
+#ifdef LIBXML_DEBUG_ENABLED
xmlDocPtr doc;
XMLNodeList children;
writenode(doc, _root, doc->children, 1);
xmlDebugDumpDocument (out, doc);
xmlFreeDoc(doc);
+#endif
}
const string&
COPYING included with this distribution for more information.
*/
+#ifdef COMPILER_MSVC
+#pragma warning(disable:4305)
+#endif
+
#include "Wavelet.h"
#include <cassert>
--- /dev/null
+/*
+ Copyright (C) 2009 John Emmas
+
+ 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 __msvc_rubberband_h__
+#define __msvc_rubberband_h__
+
+#ifdef RUBBERBAND_IS_IN_WIN_STATIC_LIB // #define if your project uses librubberband (under Windows) as a static library
+#define RUBBERBAND_IS_IN_WINDLL 0
+#endif
+
+#if !defined(RUBBERBAND_IS_IN_WINDLL)
+ #if defined(COMPILER_MSVC) || defined(COMPILER_MINGW)
+ // If you need '__declspec' compatibility, add extra compilers to the above as necessary
+ #define RUBBERBAND_IS_IN_WINDLL 1
+ #else
+ #define RUBBERBAND_IS_IN_WINDLL 0
+ #endif
+#endif
+
+#if RUBBERBAND_IS_IN_WINDLL && !defined(RUBBERBAND_API)
+ #if defined(BUILDING_RUBBERBAND)
+ #define RUBBERBAND_API __declspec(dllexport)
+ #define RUBBERBAND_APICALLTYPE __stdcall
+ #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point
+ #define RUBBERBAND_API __declspec(dllimport)
+ #define RUBBERBAND_APICALLTYPE __stdcall
+ #else
+ #error "Attempting to define __declspec with an incompatible compiler !"
+ #endif
+#elif !defined(RUBBERBAND_API)
+ // Other compilers / platforms could be accommodated here
+ #define RUBBERBAND_API
+ #define RUBBERBAND_APICALLTYPE
+ #define GETOPT_API
+ #define GETOPT_APICALLTYPE
+#endif
+
+#ifndef GETOPT_API
+ #if defined(BUILDING_GETOPT)
+ #define GETOPT_API __declspec(dllexport)
+ #define GETOPT_APICALLTYPE __cdecl
+ #elif defined(COMPILER_MSVC) || defined(COMPILER_MINGW) // Probably needs Cygwin too, at some point
+ #define GETOPT_API __declspec(dllimport)
+ #define GETOPT_APICALLTYPE __cdecl
+ #else
+ #error "Attempting to define __declspec with an incompatible compiler !"
+ #endif
+#endif // GETOPT_API
+
+#ifdef COMPILER_MSVC
+#include <rpc.h>
+
+#ifndef __THROW
+#define __THROW throw()
+#endif
+
+namespace RubberBand {
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+// These are used to replicate 'dirent.h' functionality
+// RUBBERBAND_API int RUBBERBAND_APICALLTYPE placeholder();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+} // namespace Rubberband
+
+#endif // COMPILER_MSVC
+#endif // __msvc_rubberband_h__
#include <time.h>
#else
#include "sysutils.h"
-#ifndef _WIN32
+#ifndef PLATFORM_WINDOWS
#include <sys/time.h>
#endif
#endif
#include <cstring>
-#ifndef _WIN32
+#ifndef PLATFORM_WINDOWS
#include <sys/mman.h>
#endif
//#define DEBUG_RINGBUFFER 1
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
#define MLOCK(a,b) 1
#define MUNLOCK(a,b) 1
#else
#include <list>
#include <iostream>
-#ifndef WIN32
+#ifndef PLATFORM_WINDOWS
#include <sys/time.h>
#endif
COPYING included with this distribution for more information.
*/
+#ifdef COMPILER_MSVC
+#include "bsd-3rdparty/float_cast/float_cast.h"
+#endif
#include "StretchCalculator.h"
#include <algorithm>
COPYING included with this distribution for more information.
*/
+#ifdef COMPILER_MSVC
+#include "bsd-3rdparty/float_cast/float_cast.h"
+#endif
#include "StretcherImpl.h"
#include "PercussiveAudioCurve.h"
#include "HighFrequencyAudioCurve.h"
#include <cstdlib>
#include <iostream>
-#include <cstdlib>
-#include <cstdlib>
+#ifndef COMPILER_MSVC
#include <sys/time.h>
#include <time.h>
+#endif
using std::cerr;
using std::endl;
namespace RubberBand
{
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
Thread::Thread() :
m_id(0),
SetEvent(m_condition);
}
-#else /* !_WIN32 */
+#else /* !PLATFORM_WINDOWS */
Thread::Thread() :
pthread_cond_signal(&m_condition);
}
-#endif /* !_WIN32 */
+#endif /* !PLATFORM_WINDOWS */
MutexLocker::MutexLocker(Mutex *mutex) :
m_mutex(mutex)
#ifndef _RUBBERBAND_THREAD_H_
#define _RUBBERBAND_THREAD_H_
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
#include <windows.h>
-#else /* !_WIN32 */
+#else /* !PLATFORM_WINDOWS */
#include <pthread.h>
-#endif /* !_WIN32 */
+#endif /* !PLATFORM_WINDOWS */
#include <string>
class Thread
{
public:
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
typedef HANDLE Id;
#else
typedef pthread_t Id;
virtual void run() = 0;
private:
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
HANDLE m_id;
bool m_extant;
static DWORD WINAPI staticRun(LPVOID lpParam);
bool trylock();
private:
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
HANDLE m_mutex;
#ifndef NO_THREAD_CHECKS
DWORD m_lockedBy;
private:
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
HANDLE m_mutex;
HANDLE m_condition;
bool m_locked;
** long int lrint (double x) ;
*/
+#ifndef __FLOAT_CAST_H__ // Added by JE - 30-11-2009
+#define __FLOAT_CAST_H__
+
#if (defined (WIN32) || defined (_WIN32))
#include <math.h>
#endif
-
+#endif // __FLOAT_CAST_H__
#include <cstring>
#include "sysutils.h"
-#ifdef __MSVC__
+#ifdef COMPILER_MSVC
#include "bsd-3rdparty/getopt/getopt.h"
#else
#include <getopt.h>
using namespace std;
using namespace RubberBand;
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
using RubberBand::gettimeofday;
using RubberBand::usleep;
#endif
cerr << "Using time ratio " << ratio;
cerr << " and frequency ratio " << frequencyshift << endl;
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
RubberBand::
#endif
timeval tv;
}
delete[] obf;
} else {
+#ifdef PLATFORM_WINDOWS
+ RubberBand::usleep(10000);
+#else
usleep(10000);
+#endif
}
}
cerr << "in: " << countIn << ", out: " << countOut << ", ratio: " << float(countOut)/float(countIn) << ", ideal output: " << lrint(countIn * ratio) << ", error: " << abs(lrint(countIn * ratio) - int(countOut)) << endl;
-#ifdef _WIN32
+#ifdef PLATFORM_WINDOWS
RubberBand::
#endif
timeval etv;
#ifndef _RUBBERBAND_SYSINFO_H_
#define _RUBBERBAND_SYSINFO_H_
-#ifdef __MSVC__
+#ifdef COMPILER_MSVC
#include "bsd-3rdparty/float_cast/float_cast.h"
#define R__ __restrict
#endif
#define R__
#endif
-#ifdef __MINGW32__
+#ifdef COMPILER_MINGW
#include <malloc.h>
#endif
-#ifdef __MSVC__
+#ifdef COMPILER_MSVC
#define alloca _alloca
#endif
#include "timecode/time.h"
+#include "ardour/visibility.h"
+
namespace ARDOUR {
class Session;
class SessionEvent;
}
-class BasicUI {
+#ifdef ARDOURCP_DLL_EXPORTS // defined if we are building the ARDOUR Control Protocol DLL (instead of using it)
+ #define ARDOURCP_API LIBARDOUR_HELPER_DLL_EXPORT
+#else
+ #define ARDOURCP_API LIBARDOUR_HELPER_DLL_IMPORT
+#endif
+#define ARDOURCP_LOCAL LIBARDOUR_HELPER_DLL_LOCAL
+
+class ARDOURCP_API BasicUI {
public:
BasicUI (ARDOUR::Session&);
virtual ~BasicUI ();
#include "control_protocol/basic_ui.h"
#include "control_protocol/types.h"
+#ifdef ARDOURSURFACE_DLL_EXPORTS // defined if we are building the ARDOUR surface DLLs (instead of using them)
+ #define ARDOURSURFACE_API LIBARDOUR_HELPER_DLL_EXPORT
+#else
+ #define ARDOURSURFACE_API LIBARDOUR_HELPER_DLL_IMPORT
+#endif
+#define ARDOURSURFACE_LOCAL LIBARDOUR_HELPER_DLL_LOCAL
+
namespace ARDOUR {
class Route;
class Session;
class Bundle;
-class ControlProtocol : public PBD::Stateful, public PBD::ScopedConnectionList, public BasicUI
+class ARDOURCP_API ControlProtocol : public PBD::Stateful, public PBD::ScopedConnectionList, public BasicUI
{
public:
ControlProtocol (Session&, std::string name);
void prev_track (uint32_t initial_id);
private:
- ControlProtocol (const ControlProtocol&); /* noncopyable */
+ ARDOURSURFACE_LOCAL ControlProtocol (const ControlProtocol&); /* noncopyable */
};
extern "C" {
obj.export_includes = ['.', './control_protocol' ]
obj.cxxflags = '-DPACKAGE="ardour_cp" -fPIC'
obj.includes = ['.', './control_protocol']
+ obj.defines = [ 'ARDOURCP_DLL_EXPORTS' ]
obj.name = 'libardour_cp'
obj.target = 'ardourcp'
obj.use = 'ardour libtimecode'
{
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))
static const char* const midi_map_dir_name = "midi_maps";
static const char* const midi_map_suffix = ".map";
-SearchPath
+Searchpath
system_midi_map_search_path ()
{
bool midimap_path_defined = false;
return spath_env;
}
- SearchPath spath (ardour_data_search_path());
+ Searchpath spath (ardour_data_search_path());
spath.add_subdirectory_to_paths(midi_map_dir_name);
return spath;
}
}
static bool
-midi_map_filter (const string &str, void */*arg*/)
+midi_map_filter (const string &str, void* /*arg*/)
{
return (str.length() > strlen(midi_map_suffix) &&
str.find (midi_map_suffix) == (str.length() - strlen (midi_map_suffix)));
{
vector<string *> *midi_maps;
PathScanner scanner;
- SearchPath spath (system_midi_map_search_path());
+ Searchpath spath (system_midi_map_search_path());
spath += user_midi_map_directory ();
midi_maps = scanner (spath.to_string(), midi_map_filter, 0, false, true);
using namespace ARDOUR;
-ControlProtocol*
+ControlProtocol* ARDOURSURFACE_LOCAL
new_generic_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, Session* s)
{
GenericMidiControlProtocol* gmcp;
return gmcp;
}
-void
+void ARDOURSURFACE_LOCAL
delete_generic_midi_protocol (ControlProtocolDescriptor* /*descriptor*/, ControlProtocol* cp)
{
delete cp;
}
-bool
+bool ARDOURSURFACE_LOCAL
probe_generic_midi_protocol (ControlProtocolDescriptor* /*descriptor*/)
{
return GenericMidiControlProtocol::probe ();
}
+// Field names commented out by JE - 06-01-2010
static ControlProtocolDescriptor generic_midi_descriptor = {
- name : "Generic MIDI",
- id : "uri://ardour.org/surfaces/generic_midi:0",
- ptr : 0,
- module : 0,
- mandatory : 0,
- supports_feedback : true,
- probe : probe_generic_midi_protocol,
- initialize : new_generic_midi_protocol,
- destroy : delete_generic_midi_protocol
+ /*name : */ "Generic MIDI",
+ /*id : */ "uri://ardour.org/surfaces/generic_midi:0",
+ /*ptr : */ 0,
+ /*module : */ 0,
+ /*mandatory : */ 0,
+ /*supports_feedback : */ true,
+ /*probe : */ probe_generic_midi_protocol,
+ /*initialize : */ new_generic_midi_protocol,
+ /*destroy : */ delete_generic_midi_protocol
};
-
-extern "C" {
-ControlProtocolDescriptor*
-protocol_descriptor () {
- return &generic_midi_descriptor;
-}
-}
+extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &generic_midi_descriptor; }
#include "pbd/xml++.h"
#include "pbd/stacktrace.h"
+#include "midi++/types.h" // Added by JE - 06-01-2009. All instances of 'byte' changed to 'MIDI::byte' (for clarification)
+#include "midi++/port.h"
#include "midi++/channel.h"
#include "ardour/async_midi_port.h"
last_controllable_value = 0.0f;
control_type = none;
_control_description = "MIDI Control: none";
- control_additional = (byte) -1;
+ control_additional = (MIDI::byte) -1;
feedback = true; // for now
}
last_controllable_value = 0.0f;
control_type = none;
_control_description = "MIDI Control: none";
- control_additional = (byte) -1;
+ control_additional = (MIDI::byte) -1;
feedback = true; // for now
}
{
midi_forget ();
control_type = none;
- control_additional = (byte) -1;
+ control_additional = (MIDI::byte) -1;
}
void
}
void
-MIDIControllable::midi_sense_program_change (Parser &, byte msg)
+MIDIControllable::midi_sense_program_change (Parser &, MIDI::byte msg)
{
if (!controllable) {
if (lookup_controllable ()) {
}
void
-MIDIControllable::midi_receiver (Parser &, byte *msg, size_t /*len*/)
+MIDIControllable::midi_receiver (Parser &, MIDI::byte *msg, size_t /*len*/)
{
/* we only respond to channel messages */
obj.includes = ['.', './generic_midi']
obj.name = 'libardour_generic_midi'
obj.target = 'ardour_generic_midi'
+ obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.uselib = 'GTKMM GTK GDK'
obj.use = 'libardour libardour_cp libgtkmm2ext libpbd'
obj.vnum = LIBARDOUR_GENERIC_MIDI_LIB_VERSION
#include "pbd/xml++.h"
#include "pbd/error.h"
#include "pbd/pathscanner.h"
+#include "pbd/convert.h"
#include "ardour/filesystem_paths.h"
/* strip count is mandatory */
if ((child = node.child ("Strips")) != 0) {
if ((prop = child->property ("value")) != 0) {
- if ((_strip_cnt = atoi (prop->value())) == 0) {
+ if ((_strip_cnt = atoi (prop->value().c_str())) == 0) {
_strip_cnt = 8;
}
}
if ((child = node.child ("Extenders")) != 0) {
if ((prop = child->property ("value")) != 0) {
- if ((_extenders = atoi (prop->value())) == 0) {
+ if ((_extenders = atoi (prop->value().c_str())) == 0) {
_extenders = 0;
}
}
static const char* const devinfo_dir_name = "mcp";
static const char* const devinfo_suffix = ".device";
-static SearchPath
+static Searchpath
devinfo_search_path ()
{
bool devinfo_path_defined = false;
return spath_env;
}
- SearchPath spath (ardour_data_search_path());
+ Searchpath spath (ardour_data_search_path());
spath.add_subdirectory_to_paths(devinfo_dir_name);
return spath;
}
static bool
-devinfo_filter (const string &str, void */*arg*/)
+devinfo_filter (const string &str, void* /*arg*/)
{
return (str.length() > strlen(devinfo_suffix) &&
str.find (devinfo_suffix) == (str.length() - strlen (devinfo_suffix)));
vector<string> s;
vector<string *> *devinfos;
PathScanner scanner;
- SearchPath spath (devinfo_search_path());
+ Searchpath spath (devinfo_search_path());
devinfos = scanner (spath.to_string(), devinfo_filter, 0, false, true);
device_info.clear ();
static const char* const devprofile_dir_name = "mcp";
static const char* const devprofile_suffix = ".profile";
-static SearchPath
+static Searchpath
devprofile_search_path ()
{
bool devprofile_path_defined = false;
return spath_env;
}
- SearchPath spath (ardour_data_search_path());
+ Searchpath spath (ardour_data_search_path());
spath.add_subdirectory_to_paths(devprofile_dir_name);
return spath;
}
static bool
-devprofile_filter (const string &str, void */*arg*/)
+devprofile_filter (const string &str, void* /*arg*/)
{
return (str.length() > strlen(devprofile_suffix) &&
str.find (devprofile_suffix) == (str.length() - strlen (devprofile_suffix)));
vector<string> s;
vector<string *> *devprofiles;
PathScanner scanner;
- SearchPath spath (devprofile_search_path());
+ Searchpath spath (devprofile_search_path());
devprofiles = scanner (spath.to_string(), devprofile_filter, 0, false, true);
device_profiles.clear ();
using namespace PBD;
using namespace std;
-ControlProtocol*
+static ControlProtocol*
new_mackie_protocol (ControlProtocolDescriptor*, Session* s)
{
MackieControlProtocol* mcp = 0;
return mcp;
}
-void
+static void
delete_mackie_protocol (ControlProtocolDescriptor*, ControlProtocol* cp)
{
try
So anything that can be changed in the UI should not be used here to
prevent loading of the lib.
*/
-bool
+static bool
probe_mackie_protocol (ControlProtocolDescriptor*)
{
return MackieControlProtocol::probe();
}
+// Field names commented out by JE - 06-01-2010
static ControlProtocolDescriptor mackie_descriptor = {
- name : "Mackie",
- id : "uri://ardour.org/surfaces/mackie:0",
- ptr : 0,
- module : 0,
- mandatory : 0,
+ /*name : */ "Mackie",
+ /*id : */ "uri://ardour.org/surfaces/mackie:0",
+ /*ptr : */ 0,
+ /*module : */ 0,
+ /*mandatory : */ 0,
// actually, the surface does support feedback, but all this
// flag does is show a submenu on the UI, which is useless for the mackie
// because feedback is always on. In any case, who'd want to use the
// mcu without the motorised sliders doing their thing?
- supports_feedback : false,
- probe : probe_mackie_protocol,
- initialize : new_mackie_protocol,
- destroy : delete_mackie_protocol
+ /*supports_feedback : */ false,
+ /*probe : */ probe_mackie_protocol,
+ /*initialize : */ new_mackie_protocol,
+ /*destroy : */ delete_mackie_protocol
};
-extern "C" {
-
-ControlProtocolDescriptor*
-protocol_descriptor () {
- return &mackie_descriptor;
-}
-
-}
+extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &mackie_descriptor; }
#include <float.h>
#include <sys/time.h>
#include <errno.h>
-#include <poll.h>
#include <boost/shared_array.hpp>
*/
if (!_device_info.uses_ipmidi()) {
+#ifndef PLATFORM_WINDOWS
CrossThreadChannel::drain (port->selectable());
+#endif
}
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("data available on %1\n", port->name()));
# need ../libs because some GTK2 header files require stuff there
obj.includes = ['.', '../libs']
obj.name = 'libardour_mcp'
+ obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.target = 'ardour_mcp'
obj.uselib = 'GTKMM'
obj.use = 'libardour libardour_cp libgtkmm2ext'
using namespace ARDOUR;
-ControlProtocol*
+static ControlProtocol*
new_osc_protocol (ControlProtocolDescriptor* /*descriptor*/, Session* s)
{
OSC* osc = new OSC (*s, Config->get_osc_port());
return osc;
}
-void
+static void
delete_osc_protocol (ControlProtocolDescriptor* /*descriptor*/, ControlProtocol* cp)
{
delete cp;
}
-bool
+static bool
probe_osc_protocol (ControlProtocolDescriptor* /*descriptor*/)
{
return true; // we can always do OSC
destroy : delete_osc_protocol
};
-extern "C" {
-ControlProtocolDescriptor*
-protocol_descriptor () {
- return &osc_descriptor;
-}
-}
+extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &osc_descriptor; }
#include <unistd.h>
#include <fcntl.h>
+#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include <pbd/pthread_utils.h>
int fd = mkstemp(tmpstr);
if (fd >= 0 ) {
- unlink (tmpstr);
+ ::g_unlink (tmpstr);
close (fd);
_osc_unix_server = lo_server_new (tmpstr, error_callback);
}
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
obj.cxxflags = '-DPACKAGE="ardour_cp"'
obj.includes = ['.', './osc']
obj.name = 'libardour_osc'
+ obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.target = 'ardour_osc'
obj.uselib = ' LO '
obj.use = 'libardour libardour_cp libpbd'
using namespace ARDOUR;
-ControlProtocol*
+static ControlProtocol*
new_tranzport_protocol (ControlProtocolDescriptor* descriptor, Session* s)
{
TranzportControlProtocol* tcp = new TranzportControlProtocol (*s);
}
-void
+static void
delete_tranzport_protocol (ControlProtocolDescriptor* descriptor, ControlProtocol* cp)
{
delete cp;
}
-bool
+static bool
probe_tranzport_protocol (ControlProtocolDescriptor* descriptor)
{
return TranzportControlProtocol::probe();
};
-extern "C" {
-ControlProtocolDescriptor*
-protocol_descriptor () {
- return &tranzport_descriptor;
-}
-}
+extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &tranzport_descriptor; }
+
obj.cxxflags = '-DPACKAGE="ardour_tranzport"'
obj.includes = ['.', './tranzport']
obj.name = 'libardour_tranzport'
+ obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.target = 'ardour_tranzport'
obj.use = 'libardour libardour_cp'
obj.vnum = LIBARDOUR_TRANZPORT_LIB_VERSION
using namespace ARDOUR;
using namespace PBD;
-ControlProtocol*
+static ControlProtocol*
new_wiimote_protocol (ControlProtocolDescriptor*, Session* s)
{
WiimoteControlProtocol* wmcp = new WiimoteControlProtocol (*s);
return wmcp;
}
-void
+static void
delete_wiimote_protocol (ControlProtocolDescriptor* /*descriptor*/, ControlProtocol* cp)
{
delete cp;
}
-bool
+static bool
probe_wiimote_protocol (ControlProtocolDescriptor*)
{
return WiimoteControlProtocol::probe ();
destroy : delete_wiimote_protocol
};
-
-extern "C" {
-
-ControlProtocolDescriptor*
-protocol_descriptor () {
- return &wiimote_descriptor;
-}
-
-}
+extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &wiimote_descriptor; }
obj.cxxflags = '-DPACKAGE="ardour_wiimote"'
obj.includes = ['.', '../libs']
obj.name = 'libardour_wiimote'
+ obj.defines = [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.target = 'ardour_wiimote'
obj.uselib = 'GTKMM CWIID'
obj.use = 'libardour libardour_cp libgtkmm2ext'
'control_protocol',
'frontier',
'generic_midi',
- 'mackie',
- 'osc',
- 'tranzport',
- 'wiimote'
]
def options(opt):
def configure(conf):
autowaf.set_recursive()
autowaf.configure(conf)
-
+
for i in children:
sub_config_and_use(conf, i)
+ if (conf.env['build_target'] == 'mingw'): return
+
#autowaf.check_pkg(conf, 'libusb-1.0', uselib_store='USB', mandatory=False)
#if Options.options.tranzport and conf.is_defined('HAVE_USB'):
# conf.define('BUILD_TRANZPORT', 1)
- autowaf.check_pkg (conf, 'liblo', mandatory=False, uselib_store="LO", atleast_version="0.24")
-
+ 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"):
+ sub_config_and_use(conf, 'osc')
+
conf.check_cc (header_name='cwiid.h', define_name='HAVE_CWIID_H',mandatory=False)
if conf.is_defined('HAVE_CWIID_H'):
conf.check_cc (header_name='bluetooth/bluetooth.h', define_name='HAVE_BLUETOOTH_H',mandatory=False)
autowaf.check_pkg(conf, 'cwiid', uselib_store='CWIID', atleast_version='0.6.00',mandatory=False)
if conf.is_defined ('HAVE_CWIID'):
conf.define ('BUILD_WIIMOTE', 1)
+ sub_config_and_use(conf, 'wiimote')
else:
print('You have the cwiid headers needed to compile wiimote support BUT you are missing the pkg-config file for cwiid')
else:
def build(bld):
bld.recurse('control_protocol')
- bld.recurse('generic_midi')
- bld.recurse('mackie')
+ if (bld.env['build_target'] == 'mingw'): return
+ if bld.is_defined ('BUILD_MACKIE'):
+ bld.recurse('mackie')
if bld.is_defined ('HAVE_LO'):
bld.recurse('osc')
if bld.is_defined('BUILD_WIIMOTE'):
+++ /dev/null
-./ape/apefooter.h
\ No newline at end of file
+++ /dev/null
-./ape/apeitem.h
\ No newline at end of file
+++ /dev/null
-./ape/apetag.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/attachedpictureframe.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/commentsframe.h
\ No newline at end of file
+++ /dev/null
-./flac/flacfile.h
\ No newline at end of file
+++ /dev/null
-./flac/flacproperties.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/generalencapsulatedobjectframe.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v1/id3v1genres.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v1/id3v1tag.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/id3v2extendedheader.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/id3v2footer.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/id3v2frame.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/id3v2framefactory.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/id3v2header.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/id3v2synchdata.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/id3v2tag.h
\ No newline at end of file
+++ /dev/null
-./mpc/mpcfile.h
\ No newline at end of file
+++ /dev/null
-./mpc/mpcproperties.h
\ No newline at end of file
+++ /dev/null
-./mpeg/mpegfile.h
\ No newline at end of file
+++ /dev/null
-./mpeg/mpegheader.h
\ No newline at end of file
+++ /dev/null
-./mpeg/mpegproperties.h
\ No newline at end of file
+++ /dev/null
-./ogg/oggfile.h
\ No newline at end of file
+++ /dev/null
-./ogg/flac/oggflacfile.h
\ No newline at end of file
+++ /dev/null
-./ogg/oggpage.h
\ No newline at end of file
+++ /dev/null
-./ogg/oggpageheader.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/relativevolumeframe.h
\ No newline at end of file
+++ /dev/null
-./ogg/speex/speexfile.h
\ No newline at end of file
+++ /dev/null
-./ogg/speex/speexproperties.h
\ No newline at end of file
+++ /dev/null
-./toolkit/taglib.h
\ No newline at end of file
+++ /dev/null
-./toolkit/tbytevector.h
\ No newline at end of file
+++ /dev/null
-./toolkit/tbytevectorlist.h
\ No newline at end of file
+++ /dev/null
-./toolkit/tdebug.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/textidentificationframe.h
\ No newline at end of file
+++ /dev/null
-./toolkit/tfile.h
\ No newline at end of file
+++ /dev/null
-./toolkit/tlist.h
\ No newline at end of file
+++ /dev/null
-toolkit/tlist.tcc
\ No newline at end of file
+++ /dev/null
-./toolkit/tmap.h
\ No newline at end of file
+++ /dev/null
-toolkit/tmap.tcc
\ No newline at end of file
+++ /dev/null
-./trueaudio/trueaudiofile.h
\ No newline at end of file
+++ /dev/null
-./trueaudio/trueaudioproperties.h
\ No newline at end of file
+++ /dev/null
-./toolkit/tstring.h
\ No newline at end of file
+++ /dev/null
-./toolkit/tstringlist.h
\ No newline at end of file
+++ /dev/null
-./toolkit/unicode.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/uniquefileidentifierframe.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/unknownframe.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/unsynchronizedlyricsframe.h
\ No newline at end of file
+++ /dev/null
-./mpeg/id3v2/frames/urllinkframe.h
\ No newline at end of file
+++ /dev/null
-./ogg/vorbis/vorbisfile.h
\ No newline at end of file
+++ /dev/null
-./ogg/vorbis/vorbisproperties.h
\ No newline at end of file
+++ /dev/null
-./wavpack/wavpackfile.h
\ No newline at end of file
+++ /dev/null
-./wavpack/wavpackproperties.h
\ No newline at end of file
+++ /dev/null
-./mpeg/xingheader.h
\ No newline at end of file
+++ /dev/null
-./ogg/xiphcomment.h
\ No newline at end of file
if bld.is_defined('USE_EXTERNAL_LIBS'):
return
+ # the story: taglib distributes its headers all over the place then copies them
+ # into place during an install. but we're not planning to do an install. so this
+ # doesn't work when code does #include <taglib/foo.h>.
+ #
+ # one approach is to store symlinks in the repository. but this breaks on windows
+ # where symlink support and git are not very well developed (if at all)
+ #
+ # the approach here is to copy the header files as part of the build step, if necessary
+
+ headers = [
+ './ape/apefooter.h',
+ './ape/apeitem.h',
+ './ape/apetag.h',
+ './mpeg/id3v2/frames/attachedpictureframe.h',
+ './mpeg/id3v2/frames/commentsframe.h',
+ './flac/flacfile.h',
+ './flac/flacproperties.h',
+ './mpeg/id3v2/frames/generalencapsulatedobjectframe.h',
+ './mpeg/id3v1/id3v1genres.h',
+ './mpeg/id3v1/id3v1tag.h',
+ './mpeg/id3v2/id3v2extendedheader.h',
+ './mpeg/id3v2/id3v2footer.h',
+ './mpeg/id3v2/id3v2framefactory.h',
+ './mpeg/id3v2/id3v2frame.h',
+ './mpeg/id3v2/id3v2header.h',
+ './mpeg/id3v2/id3v2synchdata.h',
+ './mpeg/id3v2/id3v2tag.h',
+ './mpc/mpcfile.h',
+ './mpc/mpcproperties.h',
+ './mpeg/mpegfile.h',
+ './mpeg/mpegheader.h',
+ './mpeg/mpegproperties.h',
+ './ogg/oggfile.h',
+ './ogg/flac/oggflacfile.h',
+ './ogg/oggpage.h',
+ './ogg/oggpageheader.h',
+ './mpeg/id3v2/frames/relativevolumeframe.h',
+ './ogg/speex/speexfile.h',
+ './ogg/speex/speexproperties.h',
+ './toolkit/taglib.h',
+ './toolkit/tbytevector.h',
+ './toolkit/tbytevectorlist.h',
+ './toolkit/tdebug.h',
+ './mpeg/id3v2/frames/textidentificationframe.h',
+ './toolkit/tfile.h',
+ './toolkit/tlist.h',
+ 'toolkit/tlist.tcc',
+ './toolkit/tmap.h',
+ 'toolkit/tmap.tcc',
+ './trueaudio/trueaudiofile.h',
+ './trueaudio/trueaudioproperties.h',
+ './toolkit/tstring.h',
+ './toolkit/tstringlist.h',
+ './toolkit/unicode.h',
+ './mpeg/id3v2/frames/uniquefileidentifierframe.h',
+ './mpeg/id3v2/frames/unknownframe.h',
+ './mpeg/id3v2/frames/unsynchronizedlyricsframe.h',
+ './mpeg/id3v2/frames/urllinkframe.h',
+ './ogg/vorbis/vorbisfile.h',
+ './ogg/vorbis/vorbisproperties.h',
+ './wavpack/wavpackfile.h',
+ './wavpack/wavpackproperties.h',
+ './mpeg/xingheader.h',
+ './ogg/xiphcomment.h',
+ ]
+
+ for h in headers:
+ tgt = bld.path.get_bld().make_node (os.path.join ('taglib', os.path.basename (h)))
+ if not os.path.exists (tgt.bldpath()):
+ bld (rule = "cp ${SRC} ${TGT}",
+ source = bld.path.make_node (os.path.join ('taglib', h)),
+ target = tgt)
+
# Library
obj = bld(features = 'cxx cxxshlib')
sources = bld.path.ant_glob('taglib/*.cpp')
taglib/ogg/speex
taglib/ogg/flac
'''.split()
- obj.export_includes = ['.', 'taglib', 'taglib/toolkit']
+ obj.export_includes = ['.', 'taglib' ]
obj.includes = include_dirs
+ obj.defines = ['MAKE_TAGLIB_LIB']
obj.name = 'libtaglib'
obj.target = 'taglib'
obj.vnum = LIBTAGLIB_LIB_VERSION
*/
+#ifdef COMPILER_MSVC
+#include <ardourext/float_cast.h>
+#endif
#include <math.h>
#include "Onset.h"
COPYING included with this distribution for more information.
*/
+#ifdef COMPILER_MSVC
+#include <ardourext/float_cast.h>
+#endif
#include "OnsetDetect.h"
#include "dsp/onsets/DetectionFunction.h"
authorization.
*/
+#ifdef COMPILER_MSVC
+#include <ardourext/float_cast.h>
+#endif
#include "PercussionOnsetDetector.h"
using std::string;
authorization.
*/
+#include <cmath>
+
+#ifdef COMPILER_MSVC
+#include <float.h>
+
+// 'std::isinf()' and 'std::isnan()' are not available in MSVC.
+#define isinf(val) !((bool)_finite((double)val))
+#define isnan(val) (bool)_isnan((double)val)
+#else
+using std::isnan;
+using std::isinf;
+#endif
+
#include "SpectralCentroid.h"
using std::string;
using std::cerr;
using std::endl;
-#include <cmath>
-
SpectralCentroid::SpectralCentroid(float inputSampleRate) :
Plugin(inputSampleRate),
Feature feature;
feature.hasTimestamp = false;
- if (!std::isnan(centroidLog) && !std::isinf(centroidLog)) {
+ if (!isnan(centroidLog) && !isinf(centroidLog)) {
feature.values.push_back(centroidLog);
}
returnFeatures[0].push_back(feature);
feature.values.clear();
- if (!std::isnan(centroidLin) && !std::isinf(centroidLin)) {
+ if (!isnan(centroidLin) && !isinf(centroidLin)) {
feature.values.push_back(centroidLin);
}
returnFeatures[1].push_back(feature);
--- /dev/null
+/*
+** Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+**
+** Permission to use, copy, modify, distribute, and sell this file for any
+** purpose is hereby granted without fee, provided that the above copyright
+** and this permission notice appear in all copies. No representations are
+** made about the suitability of this software for any purpose. It is
+** provided "as is" without express or implied warranty.
+*/
+
+/* Version 1.1 */
+
+
+/*============================================================================
+** On Intel Pentium processors (especially PIII and probably P4), converting
+** from float to int is very slow. To meet the C specs, the code produced by
+** most C compilers targeting Pentium needs to change the FPU rounding mode
+** before the float to int conversion is performed.
+**
+** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
+** is this flushing of the pipeline which is so slow.
+**
+** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
+** llrint and llrintf which fix this problem as a side effect.
+**
+** On Unix-like systems, the configure process should have detected the
+** presence of these functions. If they weren't found we have to replace them
+** here with a standard C cast.
+*/
+
+/*
+** The C99 prototypes for lrint and lrintf are as follows:
+**
+** long int lrintf (float x) ;
+** long int lrint (double x) ;
+*/
+#ifndef __FLOAT_CAST_H__ // Added by JE - 30-11-2009
+#define __FLOAT_CAST_H__
+#if (defined (WIN32) || defined (_WIN32))
+
+ #include <math.h>
+
+ /* Win32 doesn't seem to have these functions.
+ ** Therefore implement inline versions of these functions here.
+ */
+
+ __inline long int
+ lrint (double flt)
+ { int intgr;
+
+ _asm
+ { fld flt
+ fistp intgr
+ } ;
+
+ return intgr ;
+ }
+
+ __inline long int
+ lrintf (float flt)
+ { int intgr;
+
+ _asm
+ { fld flt
+ fistp intgr
+ } ;
+
+ return intgr ;
+ }
+
+ __inline long long int
+ llrint (double flt)
+ { long long int intgr;
+
+ _asm
+ { fld flt
+ fistp intgr
+ } ;
+
+ return intgr ;
+ }
+
+ __inline long long int
+ llrintf (float flt)
+ { long long int intgr;
+
+ _asm
+ { fld flt
+ fistp intgr
+ } ;
+
+ return intgr ;
+ }
+#endif
+
+#endif // __FLOAT_CAST_H__
--- /dev/null
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU CHARSET Library.
+
+ The GNU CHARSET Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU CHARSET Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with the GNU CHARSET Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin Street,
+ Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef _LIBCHARSET_H
+#define _LIBCHARSET_H
+
+#include <ardourext/localcharset.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Support for relocatable packages. */
+
+/* Sets the original and the current installation prefix of the package.
+ Relocation simply replaces a pathname starting with the original prefix
+ by the corresponding pathname with the current prefix instead. Both
+ prefixes should be directory names without trailing slash (i.e. use ""
+ instead of "/"). */
+extern void libcharset_set_relocation_prefix (const char *orig_prefix,
+ const char *curr_prefix);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _LIBCHARSET_H */
--- /dev/null
+/* Determine a canonical name for the current locale's character encoding.
+ Copyright (C) 2000-2003 Free Software Foundation, Inc.
+ This file is part of the GNU CHARSET Library.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+#ifndef _LOCALCHARSET_H
+#define _LOCALCHARSET_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Determine the current locale's character encoding, and canonicalize it
+ into one of the canonical names listed in config.charset.
+ The result must not be freed; it is statically allocated.
+ If the canonical name cannot be determined, the result is a non-canonical
+ name. */
+extern const char * locale_charset (void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _LOCALCHARSET_H */
--- /dev/null
+/*
+ Copyright (C) 2009 John Emmas
+
+ 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_msvc_extensions_h__
+#define __ardour_msvc_extensions_h__
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+#ifndef _CPP_VECTOR
+#define _CPP_VECTOR 1
+#endif
+
+#ifdef __cplusplus
+#include <vector>
+#endif
+
+#include <math.h>
+#include <float.h>
+#include <direct.h>
+#include <boost/regex.h>
+#include <glib.h>
+#include <ardourext/float_cast.h>
+
+// 'std::isnan()' is not available in MSVC. Assume '_isnan(double)'
+#define isnan(val) _isnan((double)val)
+
+// 'std::isinf()' is not available in MSVC. Assume '!_finite(double)'
+#define isinf(val) !_finite((double)val)
+
+// 'INFINITY' is not defined in MSVC. Assume 'HUGE_VAL'
+#ifndef INFINITY
+#define INFINITY HUGE_VAL
+#endif
+
+// File access modes copied from unistd.h
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+
+// Miscellaneous #defines
+#define __attribute__(x)
+#define llabs _abs64
+#define atoll _atoi64
+#define access _access
+#define getcwd _getcwd
+#define getpid _getpid
+#define snprintf _snprintf
+#define link ntfs_link
+#define unlink ntfs_unlink
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#define strtok_r( _s, _sep, _lasts ) \
+ ( *(_lasts) = strtok( (_s), (_sep) ) )
+
+#ifndef PATH_MAX
+#define PATH_MAX _MAX_PATH
+#endif
+#define DECLARE_DEFAULT_COMPARISONS(Type) \
+ extern bool operator > (const Type& lhs, const Type& rhs); \
+ extern bool operator < (const Type& lhs, const Type& rhs); \
+ extern bool operator != (const Type& lhs, const Type& rhs); \
+ extern bool operator == (const Type& lhs, const Type& rhs);
+
+// Types missing from Win32 'stat.h' (hopefully Windows
+// will either act sensibly or ignore most of them).
+#define _S_IFBLK 0x3000
+#define S_IRWXU _S_IRWXU
+#define S_IXUSR _S_IXUSR
+#define S_IWUSR _S_IWUSR
+#define S_IRUSR _S_IRUSR
+#define S_IXGRP _S_IXGRP
+#define S_IWGRP _S_IWGRP
+#define S_IRGRP _S_IRGRP
+#define S_IXOTH _S_IXOTH
+#define S_IWOTH _S_IWOTH
+#define S_IROTH _S_IROTH
+
+#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC)
+#define _S_IXUSR _S_IEXEC
+#define _S_IWUSR _S_IWRITE
+#define _S_IRUSR _S_IREAD
+#define _S_IXGRP _S_IEXEC
+#define _S_IWGRP _S_IWRITE
+#define _S_IRGRP _S_IREAD
+#define _S_IXOTH _S_IEXEC
+#define _S_IWOTH _S_IWRITE
+#define _S_IROTH _S_IREAD
+
+#define S_ISFIFO(m) _S_ISFIFO(m)
+#define S_ISDIR(m) _S_ISDIR(m)
+#define S_ISCHR(m) _S_ISCHR(m)
+#define S_ISBLK(m) _S_ISBLK(m)
+#define S_ISREG(m) _S_ISREG(m)
+
+#define _S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO)
+#define _S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+#define _S_ISCHR(m) (((m) & _S_IFMT) == _S_IFCHR)
+#define _S_ISBLK(m) (((m) & _S_IFMT) == _S_IFBLK)
+#define _S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
+
+
+#if defined(__USE_BSD) || defined(_BSD_SOURCE)
+/* Convenience macros for operations on timevals.
+ NOTE: `timercmp' does not work for >= or <=.
+ Note also that 'timerset', 'timerclear' and
+ 'timercmp' are (perhaps strangely) already
+ defined, along with various other 'time'
+ functions in WinSock.h */
+# define timeradd(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
+ if ((result)->tv_usec >= 1000000) \
+ { \
+ ++(result)->tv_sec; \
+ (result)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+# define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif /* BSD */
+
+#if !defined(__BIT_TYPES_DEFINED) || !defined(__BIT_TYPES_DEFINED__)
+#define __BIT_TYPES_DEFINED__ 1
+// Doesn't yet define all 'bit types'. Only those
+// needed by Ardour. More can be added as needed.
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef unsigned char u_int8_t;
+typedef unsigned short int u_int16_t;
+typedef unsigned int u_int32_t;
+typedef unsigned __int64 u_int64_t;
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif // __int8_t
+
+#ifndef __register_t_defined
+#define __register_t_defined
+typedef int register_t;
+#endif // __register_t
+#endif // __BIT_TYPESD
+
+// throw()
+#ifndef __THROW
+#ifdef __cplusplus
+#define __THROW throw()
+#else
+#define __THROW
+#endif
+#endif
+
+// round().... Unlike Linux, Windows doesn't seem to support the
+// concept of a system-wide (or programmable) rounding direction.
+// Fortunately, 'round to nearest' seems to be the default action
+// under Linux, so let's copy that until we find out otherwise.
+#define rint(value) round(value)
+#if !defined(PBD_API) || defined(PBD_IS_IN_WIN_STATIC_LIB)
+extern double round(double x);
+#endif
+
+// System V compatibility
+typedef unsigned short ushort;
+typedef unsigned int uint;
+
+// mode_t
+#ifndef _MODE_T_
+#define _MODE_T_
+typedef unsigned short _mode_t;
+
+#ifndef NO_OLDNAMES
+typedef _mode_t mode_t;
+#endif /* NO_OLDNAMES */
+#endif /* _MODE_T_ */
+
+// int64 abs()
+#ifdef __cplusplus // Normal 'C' doesn't permit over-ridden functions !!
+inline uint64_t abs(int64_t val)
+{
+ if (val < 0)
+ return val * (-1);
+ else
+ return val;
+}
+#endif
+
+// fmin() and fmax()
+#define fmin(a, b) min((double)a, (double)b)
+#define fmax(a, b) max((double)a, (double)b)
+
+// approximate POSIX pipe()
+#define pipe(handles) _pipe(handles, 4096, _O_BINARY)
+
+// Windows mkdir() doesn't care about access privileges
+#define mkdir(path, mode) _mkdir(path)
+
+// Redefine 'ftruncate()' to use the glib-win32 version
+#define ftruncate(fd, len) g_win32_ftruncate((gint)fd, (guint)len)
+
+
+// #include the main headers for Ardour MSVC
+#ifdef __cplusplus
+#if defined(BUILDING_PBD) || defined(PBD_IS_IN_WIN_STATIC_LIB)
+#include <pbd/msvc_pbd.h>
+#endif
+#if defined(BUILDING_LIBARDOUR) || defined(LIBARDOUR_IS_IN_WIN_STATIC_LIB)
+#include <ardour/msvc_libardour.h>
+#endif
+#if defined(BUILDING_RUBBERBAND) || defined(RUBBERBAND_IS_IN_WIN_STATIC_LIB)
+#include <rubberband/msvc_rubberband.h>
+#endif
+#endif // __cplusplus
+
+#endif /* __ardour_msvc_extensions_h__ */
--- /dev/null
+#if !defined( PTHREAD_H )
+#ifdef _PTHREAD_H // Test added by JE - 12-12-2009
+#error "ardourext/pthread.h conflicts with an existing pthread library"
+#else
+#include <ardourext/ptw32/pthread.h>
+#endif /* _PTHREAD_H */
+#endif /* PTHREAD_H */
--- /dev/null
+/* This is an implementation of the threads API of POSIX 1003.1-2001.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#if !defined( PTHREAD_H )
+#ifdef _PTHREAD_H // Test added by JE - 12-12-2009
+#error "ptw32/pthread.h conflicts with an existing pthread library"
+#endif
+// Now make sure we can't accidentally include a conflicting library !!
+#define _PTHREAD_H
+#define PTHREAD_H
+
+/*
+ * See the README file for an explanation of the pthreads-win32 version
+ * numbering scheme and how the DLL is named etc.
+ */
+#define PTW32_VERSION 2,8,0,0
+#define PTW32_VERSION_STRING "2, 8, 0, 0\0"
+
+/* There are three implementations of cancel cleanup.
+ * Note that pthread.h is included in both application
+ * compilation units and also internally for the library.
+ * The code here and within the library aims to work
+ * for all reasonable combinations of environments.
+ *
+ * The three implementations are:
+ *
+ * WIN32 SEH
+ * C
+ * C++
+ *
+ * Please note that exiting a push/pop block via
+ * "return", "exit", "break", or "continue" will
+ * lead to different behaviour amongst applications
+ * depending upon whether the library was built
+ * using SEH, C++, or C. For example, a library built
+ * with SEH will call the cleanup routine, while both
+ * C++ and C built versions will not.
+ */
+
+/*
+ * Define defaults for cleanup code.
+ * Note: Unless the build explicitly defines one of the following, then
+ * we default to standard C style cleanup. This style uses setjmp/longjmp
+ * in the cancelation and thread exit implementations and therefore won't
+ * do stack unwinding if linked to applications that have it (e.g.
+ * C++ apps). This is currently consistent with most/all commercial Unix
+ * POSIX threads implementations.
+ */
+#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
+# define __CLEANUP_C
+#endif
+
+#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))
+#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.
+#endif
+
+/*
+ * Stop here if we are being included by the resource compiler.
+ */
+#ifndef RC_INVOKED
+
+#undef PTW32_LEVEL
+
+#if defined(_POSIX_SOURCE)
+#define PTW32_LEVEL 0
+/* Early POSIX */
+#endif
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 1
+/* Include 1b, 1c and 1d */
+#endif
+
+#if defined(INCLUDE_NP)
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 2
+/* Include Non-Portable extensions */
+#endif
+
+#define PTW32_LEVEL_MAX 3
+
+#if !defined(PTW32_LEVEL)
+#define PTW32_LEVEL PTW32_LEVEL_MAX
+/* Include everything */
+#endif
+
+#ifdef _UWIN
+# define HAVE_STRUCT_TIMESPEC 1
+# define HAVE_SIGNAL_H 1
+# undef HAVE_CONFIG_H
+# pragma comment(lib, "pthread")
+#endif
+
+/*
+ * -------------------------------------------------------------
+ *
+ *
+ * Module: pthread.h
+ *
+ * Purpose:
+ * Provides an implementation of PThreads based upon the
+ * standard:
+ *
+ * POSIX 1003.1-2001
+ * and
+ * The Single Unix Specification version 3
+ *
+ * (these two are equivalent)
+ *
+ * in order to enhance code portability between Windows,
+ * various commercial Unix implementations, and Linux.
+ *
+ * See the ANNOUNCE file for a full list of conforming
+ * routines and defined constants, and a list of missing
+ * routines and constants not defined in this implementation.
+ *
+ * Authors:
+ * There have been many contributors to this library.
+ * The initial implementation was contributed by
+ * John Bossom, and several others have provided major
+ * sections or revisions of parts of the implementation.
+ * Often significant effort has been contributed to
+ * find and fix important bugs and other problems to
+ * improve the reliability of the library, which sometimes
+ * is not reflected in the amount of code which changed as
+ * result.
+ * As much as possible, the contributors are acknowledged
+ * in the ChangeLog file in the source code distribution
+ * where their changes are noted in detail.
+ *
+ * Contributors are listed in the CONTRIBUTORS file.
+ *
+ * As usual, all bouquets go to the contributors, and all
+ * brickbats go to the project maintainer.
+ *
+ * Maintainer:
+ * The code base for this project is coordinated and
+ * eventually pre-tested, packaged, and made available by
+ *
+ * Ross Johnson <rpj@callisto.canberra.edu.au>
+ *
+ * QA Testers:
+ * Ultimately, the library is tested in the real world by
+ * a host of competent and demanding scientists and
+ * engineers who report bugs and/or provide solutions
+ * which are then fixed or incorporated into subsequent
+ * versions of the library. Each time a bug is fixed, a
+ * test case is written to prove the fix and ensure
+ * that later changes to the code don't reintroduce the
+ * same error. The number of test cases is slowly growing
+ * and therefore so is the code reliability.
+ *
+ * Compliance:
+ * See the file ANNOUNCE for the list of implemented
+ * and not-implemented routines and defined options.
+ * Of course, these are all defined is this file as well.
+ *
+ * Web site:
+ * The source code and other information about this library
+ * are available from
+ *
+ * http://sources.redhat.com/pthreads-win32/
+ *
+ * -------------------------------------------------------------
+ */
+
+/* Try to avoid including windows.h */
+#if defined(__MINGW32__) && defined(__cplusplus)
+#define PTW32_INCLUDE_WINDOWS_H
+#endif
+
+#ifdef PTW32_INCLUDE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)
+/*
+ * VC++6.0 or early compiler's header has no DWORD_PTR type.
+ */
+typedef unsigned long DWORD_PTR;
+#endif
+/*
+ * -----------------
+ * autoconf switches
+ * -----------------
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifndef NEED_FTIME
+#include <time.h>
+#else /* NEED_FTIME */
+/* use native WIN32 time API */
+#endif /* NEED_FTIME */
+
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif /* HAVE_SIGNAL_H */
+
+#include <setjmp.h>
+#include <limits.h>
+
+/*
+ * Boolean values to make us independent of system includes.
+ */
+enum {
+ PTW32_FALSE = 0,
+ PTW32_TRUE = (! PTW32_FALSE)
+};
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#ifndef PTW32_CONFIG_H
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+#ifdef NEED_ERRNO
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Several systems don't define some error numbers.
+ */
+#ifndef ENOTSUP
+# define ENOTSUP 48 /* This is the value in Solaris. */
+#endif
+
+#ifndef ETIMEDOUT
+# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
+#endif
+
+#ifndef ENOSYS
+# define ENOSYS 140 /* Semi-arbitrary value */
+#endif
+
+#ifndef EDEADLK
+# ifdef EDEADLOCK
+# define EDEADLK EDEADLOCK
+# else
+# define EDEADLK 36 /* This is the value in MSVC. */
+# endif
+#endif
+
+#include <ardourext/sched.h>
+
+/*
+ * To avoid including windows.h we define only those things that we
+ * actually need from it.
+ */
+#ifndef PTW32_INCLUDE_WINDOWS_H
+#ifndef HANDLE
+# define PTW32__HANDLE_DEF
+# define HANDLE void *
+#endif
+#ifndef DWORD
+# define PTW32__DWORD_DEF
+# define DWORD unsigned long
+#endif
+#endif
+
+#ifndef HAVE_STRUCT_TIMESPEC
+#define HAVE_STRUCT_TIMESPEC 1
+struct timespec {
+ long tv_sec;
+ long tv_nsec;
+};
+#endif /* HAVE_STRUCT_TIMESPEC */
+
+#ifndef SIG_BLOCK
+#define SIG_BLOCK 0
+#endif /* SIG_BLOCK */
+
+#ifndef SIG_UNBLOCK
+#define SIG_UNBLOCK 1
+#endif /* SIG_UNBLOCK */
+
+#ifndef SIG_SETMASK
+#define SIG_SETMASK 2
+#endif /* SIG_SETMASK */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * -------------------------------------------------------------
+ *
+ * POSIX 1003.1-2001 Options
+ * =========================
+ *
+ * Options are normally set in <unistd.h>, which is not provided
+ * with pthreads-win32.
+ *
+ * For conformance with the Single Unix Specification (version 3), all of the
+ * options below are defined, and have a value of either -1 (not supported)
+ * or 200112L (supported).
+ *
+ * These options can neither be left undefined nor have a value of 0, because
+ * either indicates that sysconf(), which is not implemented, may be used at
+ * runtime to check the status of the option.
+ *
+ * _POSIX_THREADS (== 200112L)
+ * If == 200112L, you can use threads
+ *
+ * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
+ * If == 200112L, you can control the size of a thread's
+ * stack
+ * pthread_attr_getstacksize
+ * pthread_attr_setstacksize
+ *
+ * _POSIX_THREAD_ATTR_STACKADDR (== -1)
+ * If == 200112L, you can allocate and control a thread's
+ * stack. If not supported, the following functions
+ * will return ENOSYS, indicating they are not
+ * supported:
+ * pthread_attr_getstackaddr
+ * pthread_attr_setstackaddr
+ *
+ * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
+ * If == 200112L, you can use realtime scheduling.
+ * This option indicates that the behaviour of some
+ * implemented functions conforms to the additional TPS
+ * requirements in the standard. E.g. rwlocks favour
+ * writers over readers when threads have equal priority.
+ *
+ * _POSIX_THREAD_PRIO_INHERIT (== -1)
+ * If == 200112L, you can create priority inheritance
+ * mutexes.
+ * pthread_mutexattr_getprotocol +
+ * pthread_mutexattr_setprotocol +
+ *
+ * _POSIX_THREAD_PRIO_PROTECT (== -1)
+ * If == 200112L, you can create priority ceiling mutexes
+ * Indicates the availability of:
+ * pthread_mutex_getprioceiling
+ * pthread_mutex_setprioceiling
+ * pthread_mutexattr_getprioceiling
+ * pthread_mutexattr_getprotocol +
+ * pthread_mutexattr_setprioceiling
+ * pthread_mutexattr_setprotocol +
+ *
+ * _POSIX_THREAD_PROCESS_SHARED (== -1)
+ * If set, you can create mutexes and condition
+ * variables that can be shared with another
+ * process.If set, indicates the availability
+ * of:
+ * pthread_mutexattr_getpshared
+ * pthread_mutexattr_setpshared
+ * pthread_condattr_getpshared
+ * pthread_condattr_setpshared
+ *
+ * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
+ * If == 200112L you can use the special *_r library
+ * functions that provide thread-safe behaviour
+ *
+ * _POSIX_READER_WRITER_LOCKS (== 200112L)
+ * If == 200112L, you can use read/write locks
+ *
+ * _POSIX_SPIN_LOCKS (== 200112L)
+ * If == 200112L, you can use spin locks
+ *
+ * _POSIX_BARRIERS (== 200112L)
+ * If == 200112L, you can use barriers
+ *
+ * + These functions provide both 'inherit' and/or
+ * 'protect' protocol, based upon these macro
+ * settings.
+ *
+ * -------------------------------------------------------------
+ */
+
+/*
+ * POSIX Options
+ */
+#undef _POSIX_THREADS
+#define _POSIX_THREADS 200112L
+
+#undef _POSIX_READER_WRITER_LOCKS
+#define _POSIX_READER_WRITER_LOCKS 200112L
+
+#undef _POSIX_SPIN_LOCKS
+#define _POSIX_SPIN_LOCKS 200112L
+
+#undef _POSIX_BARRIERS
+#define _POSIX_BARRIERS 200112L
+
+#undef _POSIX_THREAD_SAFE_FUNCTIONS
+#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
+
+#undef _POSIX_THREAD_ATTR_STACKSIZE
+#define _POSIX_THREAD_ATTR_STACKSIZE 200112L
+
+/*
+ * The following options are not supported
+ */
+#undef _POSIX_THREAD_ATTR_STACKADDR
+#define _POSIX_THREAD_ATTR_STACKADDR -1
+
+#undef _POSIX_THREAD_PRIO_INHERIT
+#define _POSIX_THREAD_PRIO_INHERIT -1
+
+#undef _POSIX_THREAD_PRIO_PROTECT
+#define _POSIX_THREAD_PRIO_PROTECT -1
+
+/* TPS is not fully supported. */
+#undef _POSIX_THREAD_PRIORITY_SCHEDULING
+#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
+
+#undef _POSIX_THREAD_PROCESS_SHARED
+#define _POSIX_THREAD_PROCESS_SHARED -1
+
+
+/*
+ * POSIX 1003.1-2001 Limits
+ * ===========================
+ *
+ * These limits are normally set in <limits.h>, which is not provided with
+ * pthreads-win32.
+ *
+ * PTHREAD_DESTRUCTOR_ITERATIONS
+ * Maximum number of attempts to destroy
+ * a thread's thread-specific data on
+ * termination (must be at least 4)
+ *
+ * PTHREAD_KEYS_MAX
+ * Maximum number of thread-specific data keys
+ * available per process (must be at least 128)
+ *
+ * PTHREAD_STACK_MIN
+ * Minimum supported stack size for a thread
+ *
+ * PTHREAD_THREADS_MAX
+ * Maximum number of threads supported per
+ * process (must be at least 64).
+ *
+ * SEM_NSEMS_MAX
+ * The maximum number of semaphores a process can have.
+ * (must be at least 256)
+ *
+ * SEM_VALUE_MAX
+ * The maximum value a semaphore can have.
+ * (must be at least 32767)
+ *
+ */
+#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+
+#undef PTHREAD_DESTRUCTOR_ITERATIONS
+#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+#undef _POSIX_THREAD_KEYS_MAX
+#define _POSIX_THREAD_KEYS_MAX 128
+
+#undef PTHREAD_KEYS_MAX
+#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX
+
+#undef PTHREAD_STACK_MIN
+#define PTHREAD_STACK_MIN 0
+
+#undef _POSIX_THREAD_THREADS_MAX
+#define _POSIX_THREAD_THREADS_MAX 64
+
+ /* Arbitrary value */
+#undef PTHREAD_THREADS_MAX
+#define PTHREAD_THREADS_MAX 2019
+
+#undef _POSIX_SEM_NSEMS_MAX
+#define _POSIX_SEM_NSEMS_MAX 256
+
+ /* Arbitrary value */
+#undef SEM_NSEMS_MAX
+#define SEM_NSEMS_MAX 1024
+
+#undef _POSIX_SEM_VALUE_MAX
+#define _POSIX_SEM_VALUE_MAX 32767
+
+#undef SEM_VALUE_MAX
+#define SEM_VALUE_MAX INT_MAX
+
+
+#if __GNUC__ && ! defined (__declspec)
+# error Please upgrade your GNU compiler to one that supports __declspec.
+#endif
+
+/*
+ * When building the DLL code, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the DLL,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#ifndef PTW32_STATIC_LIB
+# ifdef PTW32_BUILD
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * The Open Watcom C/C++ compiler uses a non-standard calling convention
+ * that passes function args in registers unless __cdecl is explicitly specified
+ * in exposed function prototypes.
+ *
+ * We force all calls to cdecl even though this could slow Watcom code down
+ * slightly. If you know that the Watcom compiler will be used to build both
+ * the DLL and application, then you can probably define this as a null string.
+ * Remember that pthread.h (this file) is used for both the DLL and application builds.
+ */
+#define PTW32_CDECL __cdecl
+
+#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
+# include <sys/types.h>
+#else
+/*
+ * Generic handle type - intended to extend uniqueness beyond
+ * that available with a simple pointer. It should scale for either
+ * IA-32 or IA-64.
+ */
+typedef struct {
+ void * p; /* Pointer to actual object */
+ unsigned int x; /* Extra information - reuse count etc */
+} ptw32_handle_t;
+
+typedef ptw32_handle_t pthread_t;
+typedef struct pthread_attr_t_ * pthread_attr_t;
+typedef struct pthread_once_t_ pthread_once_t;
+typedef struct pthread_key_t_ * pthread_key_t;
+typedef struct pthread_mutex_t_ * pthread_mutex_t;
+typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
+typedef struct pthread_cond_t_ * pthread_cond_t;
+typedef struct pthread_condattr_t_ * pthread_condattr_t;
+#endif
+typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
+typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
+typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
+typedef struct pthread_barrier_t_ * pthread_barrier_t;
+typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
+
+/*
+ * ====================
+ * ====================
+ * POSIX Threads
+ * ====================
+ * ====================
+ */
+
+enum {
+/*
+ * pthread_attr_{get,set}detachstate
+ */
+ PTHREAD_CREATE_JOINABLE = 0, /* Default */
+ PTHREAD_CREATE_DETACHED = 1,
+
+/*
+ * pthread_attr_{get,set}inheritsched
+ */
+ PTHREAD_INHERIT_SCHED = 0,
+ PTHREAD_EXPLICIT_SCHED = 1, /* Default */
+
+/*
+ * pthread_{get,set}scope
+ */
+ PTHREAD_SCOPE_PROCESS = 0,
+ PTHREAD_SCOPE_SYSTEM = 1, /* Default */
+
+/*
+ * pthread_setcancelstate paramters
+ */
+ PTHREAD_CANCEL_ENABLE = 0, /* Default */
+ PTHREAD_CANCEL_DISABLE = 1,
+
+/*
+ * pthread_setcanceltype parameters
+ */
+ PTHREAD_CANCEL_ASYNCHRONOUS = 0,
+ PTHREAD_CANCEL_DEFERRED = 1, /* Default */
+
+/*
+ * pthread_mutexattr_{get,set}pshared
+ * pthread_condattr_{get,set}pshared
+ */
+ PTHREAD_PROCESS_PRIVATE = 0,
+ PTHREAD_PROCESS_SHARED = 1,
+
+/*
+ * pthread_barrier_wait
+ */
+ PTHREAD_BARRIER_SERIAL_THREAD = -1
+};
+
+/*
+ * ====================
+ * ====================
+ * Cancelation
+ * ====================
+ * ====================
+ */
+#define PTHREAD_CANCELED ((void *) -1)
+
+
+/*
+ * ====================
+ * ====================
+ * Once Key
+ * ====================
+ * ====================
+ */
+#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0}
+
+struct pthread_once_t_
+{
+ int done; /* indicates if user function has been executed */
+ void * lock;
+ int reserved1;
+ int reserved2;
+};
+
+
+/*
+ * ====================
+ * ====================
+ * Object initialisers
+ * ====================
+ * ====================
+ */
+#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
+
+/*
+ * Compatibility with LinuxThreads
+ */
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
+
+#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
+
+#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
+
+#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
+
+
+/*
+ * Mutex types.
+ */
+enum
+{
+ /* Compatibility with LinuxThreads */
+ PTHREAD_MUTEX_FAST_NP,
+ PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
+ PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
+ /* For compatibility with POSIX */
+ PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
+ PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
+};
+
+
+typedef struct ptw32_cleanup_t ptw32_cleanup_t;
+
+#if defined(_MSC_VER)
+/* Disable MSVC 'anachronism used' warning */
+#pragma warning( disable : 4229 )
+#endif
+
+typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *);
+
+#if defined(_MSC_VER)
+#pragma warning( default : 4229 )
+#endif
+
+struct ptw32_cleanup_t
+{
+ ptw32_cleanup_callback_t routine;
+ void *arg;
+ struct ptw32_cleanup_t *prev;
+};
+
+#ifdef __CLEANUP_SEH
+ /*
+ * WIN32 SEH version of cancel cleanup.
+ */
+
+#define pthread_cleanup_push( _rout, _arg ) \
+ { \
+ ptw32_cleanup_t _cleanup; \
+ \
+ _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \
+ _cleanup.arg = (_arg); \
+ __try \
+ { \
+
+#define pthread_cleanup_pop( _execute ) \
+ } \
+ __finally \
+ { \
+ if( _execute || AbnormalTermination()) \
+ { \
+ (*(_cleanup.routine))( _cleanup.arg ); \
+ } \
+ } \
+ }
+
+#else /* __CLEANUP_SEH */
+
+#ifdef __CLEANUP_C
+
+ /*
+ * C implementation of PThreads cancel cleanup
+ */
+
+#define pthread_cleanup_push( _rout, _arg ) \
+ { \
+ ptw32_cleanup_t _cleanup; \
+ \
+ ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
+
+#define pthread_cleanup_pop( _execute ) \
+ (void) ptw32_pop_cleanup( _execute ); \
+ }
+
+#else /* __CLEANUP_C */
+
+#ifdef __CLEANUP_CXX
+
+ /*
+ * C++ version of cancel cleanup.
+ * - John E. Bossom.
+ */
+
+ class PThreadCleanup {
+ /*
+ * PThreadCleanup
+ *
+ * Purpose
+ * This class is a C++ helper class that is
+ * used to implement pthread_cleanup_push/
+ * pthread_cleanup_pop.
+ * The destructor of this class automatically
+ * pops the pushed cleanup routine regardless
+ * of how the code exits the scope
+ * (i.e. such as by an exception)
+ */
+ ptw32_cleanup_callback_t cleanUpRout;
+ void * obj;
+ int executeIt;
+
+ public:
+ PThreadCleanup() :
+ cleanUpRout( 0 ),
+ obj( 0 ),
+ executeIt( 0 )
+ /*
+ * No cleanup performed
+ */
+ {
+ }
+
+ PThreadCleanup(
+ ptw32_cleanup_callback_t routine,
+ void * arg ) :
+ cleanUpRout( routine ),
+ obj( arg ),
+ executeIt( 1 )
+ /*
+ * Registers a cleanup routine for 'arg'
+ */
+ {
+ }
+
+ ~PThreadCleanup()
+ {
+ if ( executeIt && ((void *) cleanUpRout != (void *) 0) )
+ {
+ (void) (*cleanUpRout)( obj );
+ }
+ }
+
+ void execute( int exec )
+ {
+ executeIt = exec;
+ }
+ };
+
+ /*
+ * C++ implementation of PThreads cancel cleanup;
+ * This implementation takes advantage of a helper
+ * class who's destructor automatically calls the
+ * cleanup routine if we exit our scope weirdly
+ */
+#define pthread_cleanup_push( _rout, _arg ) \
+ { \
+ PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \
+ (void *) (_arg) );
+
+#define pthread_cleanup_pop( _execute ) \
+ cleanup.execute( _execute ); \
+ }
+
+#else
+
+#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
+
+#endif /* __CLEANUP_CXX */
+
+#endif /* __CLEANUP_C */
+
+#endif /* __CLEANUP_SEH */
+
+/*
+ * ===============
+ * ===============
+ * Methods
+ * ===============
+ * ===============
+ */
+
+/*
+ * PThread Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr,
+ int *detachstate);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr,
+ void **stackaddr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr,
+ size_t * stacksize);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr,
+ int detachstate);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr,
+ void *stackaddr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr,
+ size_t stacksize);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr,
+ struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr,
+ const struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *,
+ int);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (pthread_attr_t *,
+ int *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr,
+ int inheritsched);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr,
+ int * inheritsched);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *,
+ int);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *,
+ int *);
+
+/*
+ * PThread Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
+ const pthread_attr_t * attr,
+ void *(*start) (void *),
+ void *arg);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1,
+ pthread_t t2);
+
+PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread,
+ void **value_ptr);
+
+PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state,
+ int *oldstate);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type,
+ int *oldtype);
+
+PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control,
+ void (*init_routine) (void));
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute);
+
+PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
+ void (*routine) (void *),
+ void *arg);
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Thread Specific Data Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key,
+ void (*destructor) (void *));
+
+PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key,
+ const void *value);
+
+PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key);
+
+
+/*
+ * Mutex Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t
+ * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
+ int pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind);
+
+/*
+ * Barrier Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t
+ * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
+ int pshared);
+
+/*
+ * Mutex Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex,
+ const pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex);
+
+/*
+ * Spinlock Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock);
+
+/*
+ * Barrier Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier,
+ const pthread_barrierattr_t * attr,
+ unsigned int count);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier);
+
+/*
+ * Condition Variable Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr,
+ int pshared);
+
+/*
+ * Condition Variable Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond,
+ const pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond);
+
+/*
+ * Scheduling
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread,
+ int policy,
+ const struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread,
+ int *policy,
+ struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void);
+
+/*
+ * Read-Write Lock Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock,
+ const pthread_rwlockattr_t *attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
+ int pshared);
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
+
+/*
+ * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
+ * already have signal.h that don't define these.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig);
+
+/*
+ * Non-portable functions
+ */
+
+/*
+ * Compatibility with Linux.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
+ int kind);
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
+ int *kind);
+
+/*
+ * Possibly supported by other POSIX threads implementations
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval);
+PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void);
+
+/*
+ * Useful if an application wants to statically link
+ * the lib rather than load the DLL at run-time.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void);
+
+/*
+ * Features that are auto-detected at load/run time.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int);
+enum ptw32_features {
+ PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */
+ PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */
+};
+
+/*
+ * Register a system time change with the library.
+ * Causes the library to perform various functions
+ * in response to the change. Should be called whenever
+ * the application's top level window receives a
+ * WM_TIMECHANGE message. It can be passed directly to
+ * pthread_create() as a new thread if desired.
+ */
+PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *);
+
+#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+
+/*
+ * Returns the Win32 HANDLE for the POSIX thread.
+ */
+PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread);
+
+
+/*
+ * Protected Methods
+ *
+ * This function blocks until the given WIN32 handle
+ * is signaled or pthread_cancel had been called.
+ * This function allows the caller to hook into the
+ * PThreads cancel mechanism. It is implemented using
+ *
+ * WaitForMultipleObjects
+ *
+ * on 'waitHandle' and a manually reset WIN32 Event
+ * used to implement pthread_cancel. The 'timeout'
+ * argument to TimedWait is simply passed to
+ * WaitForMultipleObjects.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle);
+PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle,
+ DWORD timeout);
+
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Thread-Safe C Runtime Library Mappings.
+ */
+#ifndef _UWIN
+# if defined(NEED_ERRNO)
+ PTW32_DLLPORT int * PTW32_CDECL _errno( void );
+# else
+# ifndef errno
+# if (defined(_MT) || defined(_DLL))
+ __declspec(dllimport) extern int * __cdecl _errno(void);
+# define errno (*_errno())
+# endif
+# endif
+# endif
+#endif
+
+/*
+ * WIN32 C runtime library had been made thread-safe
+ * without affecting the user interface. Provide
+ * mappings from the UNIX thread-safe versions to
+ * the standard C runtime library calls.
+ * Only provide function mappings for functions that
+ * actually exist on WIN32.
+ */
+
+#if !defined(__MINGW32__)
+#define strtok_r( _s, _sep, _lasts ) \
+ ( *(_lasts) = strtok( (_s), (_sep) ) )
+#endif /* !__MINGW32__ */
+
+#define asctime_r( _tm, _buf ) \
+ ( strcpy( (_buf), asctime( (_tm) ) ), \
+ (_buf) )
+
+#define ctime_r( _clock, _buf ) \
+ ( strcpy( (_buf), ctime( (_clock) ) ), \
+ (_buf) )
+
+#define gmtime_r( _clock, _result ) \
+ ( *(_result) = *gmtime( (_clock) ), \
+ (_result) )
+
+#define localtime_r( _clock, _result ) \
+ ( *(_result) = *localtime( (_clock) ), \
+ (_result) )
+
+#define rand_r( _seed ) \
+ ( _seed == _seed? rand() : rand() )
+
+
+/*
+ * Some compiler environments don't define some things.
+ */
+#if defined(__BORLANDC__)
+# define _ftime ftime
+# define _timeb timeb
+#endif
+
+#ifdef __cplusplus
+
+/*
+ * Internal exceptions
+ */
+class ptw32_exception {};
+class ptw32_exception_cancel : public ptw32_exception {};
+class ptw32_exception_exit : public ptw32_exception {};
+
+#endif
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+
+/* FIXME: This is only required if the library was built using SEH */
+/*
+ * Get internal SEH tag
+ */
+PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void);
+
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+#ifndef PTW32_BUILD
+
+#ifdef __CLEANUP_SEH
+
+/*
+ * Redefine the SEH __except keyword to ensure that applications
+ * propagate our internal exceptions up to the library's internal handlers.
+ */
+#define __except( E ) \
+ __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
+ ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
+
+#endif /* __CLEANUP_SEH */
+
+#ifdef __CLEANUP_CXX
+
+/*
+ * Redefine the C++ catch keyword to ensure that applications
+ * propagate our internal exceptions up to the library's internal handlers.
+ */
+#ifdef _MSC_VER
+ /*
+ * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
+ * if you want Pthread-Win32 cancelation and pthread_exit to work.
+ */
+
+#ifndef PtW32NoCatchWarn
+
+#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
+#pragma message("------------------------------------------------------------------")
+#pragma message("When compiling applications with MSVC++ and C++ exception handling:")
+#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads")
+#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
+#pragma message(" cancelation and pthread_exit to work. For example:")
+#pragma message("")
+#pragma message(" #ifdef PtW32CatchAll")
+#pragma message(" PtW32CatchAll")
+#pragma message(" #else")
+#pragma message(" catch(...)")
+#pragma message(" #endif")
+#pragma message(" {")
+#pragma message(" /* Catchall block processing */")
+#pragma message(" }")
+#pragma message("------------------------------------------------------------------")
+
+#endif
+
+#define PtW32CatchAll \
+ catch( ptw32_exception & ) { throw; } \
+ catch( ... )
+
+#else /* _MSC_VER */
+
+#define catch( E ) \
+ catch( ptw32_exception & ) { throw; } \
+ catch( E )
+
+#endif /* _MSC_VER */
+
+#endif /* __CLEANUP_CXX */
+
+#endif /* ! PTW32_BUILD */
+
+#ifdef __cplusplus
+} /* End of extern "C" */
+#endif /* __cplusplus */
+
+#ifdef PTW32__HANDLE_DEF
+# undef HANDLE
+#endif
+#ifdef PTW32__DWORD_DEF
+# undef DWORD
+#endif
+
+#undef PTW32_LEVEL
+#undef PTW32_LEVEL_MAX
+
+#endif /* ! RC_INVOKED */
+
+#endif /* PTHREAD_H */
--- /dev/null
+/*
+ * Module: sched.h
+ *
+ * Purpose:
+ * Provides an implementation of POSIX realtime extensions
+ * as defined in
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef SCHED_H
+#ifdef _SCHED_H // Test added by JE - 12-12-2009
+#error "ardourext/sched.h conflicts with an existing pthread library"
+#endif
+// Now make sure we can't accidentally include a conflicting library !!
+#define _SCHED_H
+#define SCHED_H
+
+#undef PTW32_LEVEL
+
+#if defined(_POSIX_SOURCE)
+#define PTW32_LEVEL 0
+/* Early POSIX */
+#endif
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 1
+/* Include 1b, 1c and 1d */
+#endif
+
+#if defined(INCLUDE_NP)
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 2
+/* Include Non-Portable extensions */
+#endif
+
+#define PTW32_LEVEL_MAX 3
+
+#if !defined(PTW32_LEVEL)
+#define PTW32_LEVEL PTW32_LEVEL_MAX
+/* Include everything */
+#endif
+
+
+#if __GNUC__ && ! defined (__declspec)
+# error Please upgrade your GNU compiler to one that supports __declspec.
+#endif
+
+/*
+ * When building the DLL code, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the DLL,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#ifndef PTW32_STATIC_LIB
+# ifdef PTW32_BUILD
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#ifndef PTW32_CONFIG_H
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+#ifdef NEED_ERRNO
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+#if defined(__MINGW32__) || defined(_UWIN)
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+/* For pid_t */
+# include <sys/types.h>
+/* Required by Unix 98 */
+# include <time.h>
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+#else
+typedef int pid_t;
+#endif
+
+/* Thread scheduling policies */
+
+enum {
+ SCHED_OTHER = 0,
+ SCHED_FIFO,
+ SCHED_RR,
+ SCHED_MIN = SCHED_OTHER,
+ SCHED_MAX = SCHED_RR
+};
+
+struct sched_param {
+ int sched_priority;
+};
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+PTW32_DLLPORT int __cdecl sched_yield (void);
+
+PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy);
+
+PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy);
+
+PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy);
+
+PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid);
+
+/*
+ * Note that this macro returns ENOTSUP rather than
+ * ENOSYS as might be expected. However, returning ENOSYS
+ * should mean that sched_get_priority_{min,max} are
+ * not implemented as well as sched_rr_get_interval.
+ * This is not the case, since we just don't support
+ * round-robin scheduling. Therefore I have chosen to
+ * return the same value as sched_setscheduler when
+ * SCHED_RR is passed to it.
+ */
+#define sched_rr_get_interval(_pid, _interval) \
+ ( errno = ENOTSUP, (int) -1 )
+
+
+#ifdef __cplusplus
+} /* End of extern "C" */
+#endif /* __cplusplus */
+
+#undef PTW32_LEVEL
+#undef PTW32_LEVEL_MAX
+
+#endif /* !SCHED_H */
+
--- /dev/null
+/*
+ * Module: semaphore.h
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#if !defined( SEMAPHORE_H )
+#ifdef _SEMAPHORE_H // Test added by JE - 12-12-2009
+#error "ardourext/semaphore.h conflicts with an existing pthread library"
+#endif
+// Now make sure we can't accidentally include a conflicting library !!
+#define _SEMAPHORE_H
+#define SEMAPHORE_H
+
+#undef PTW32_LEVEL
+
+#if defined(_POSIX_SOURCE)
+#define PTW32_LEVEL 0
+/* Early POSIX */
+#endif
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 1
+/* Include 1b, 1c and 1d */
+#endif
+
+#if defined(INCLUDE_NP)
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 2
+/* Include Non-Portable extensions */
+#endif
+
+#define PTW32_LEVEL_MAX 3
+
+#if !defined(PTW32_LEVEL)
+#define PTW32_LEVEL PTW32_LEVEL_MAX
+/* Include everything */
+#endif
+
+#if __GNUC__ && ! defined (__declspec)
+# error Please upgrade your GNU compiler to one that supports __declspec.
+#endif
+
+/*
+ * When building the DLL code, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the DLL,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#ifndef PTW32_STATIC_LIB
+# ifdef PTW32_BUILD
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#ifndef PTW32_CONFIG_H
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+#ifdef NEED_ERRNO
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+#define _POSIX_SEMAPHORES
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#ifndef HAVE_MODE_T
+typedef unsigned int mode_t;
+#endif
+
+
+typedef struct sem_t_ * sem_t;
+
+PTW32_DLLPORT int __cdecl sem_init (sem_t * sem,
+ int pshared,
+ unsigned int value);
+
+PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem,
+ const struct timespec * abstime);
+
+PTW32_DLLPORT int __cdecl sem_post (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem,
+ int count);
+
+PTW32_DLLPORT int __cdecl sem_open (const char * name,
+ int oflag,
+ mode_t mode,
+ unsigned int value);
+
+PTW32_DLLPORT int __cdecl sem_close (sem_t * sem);
+
+PTW32_DLLPORT int __cdecl sem_unlink (const char * name);
+
+PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem,
+ int * sval);
+
+#ifdef __cplusplus
+} /* End of extern "C" */
+#endif /* __cplusplus */
+
+#undef PTW32_LEVEL
+#undef PTW32_LEVEL_MAX
+
+#endif /* !SEMAPHORE_H */
--- /dev/null
+#ifndef _TARGETSXS_H_
+#define _TARGETSXS_H_
+
+#pragma warning( disable : 4996 )
+
+#ifndef LV2_SUPPORT
+#define LV2_SUPPORT 1
+#define HAVE_SUIL 1
+#define HAVE_LV2 1
+//#define HAVE_NEW_LV2 1
+/* Comment out the above lines to build Mixbus without LV2 support */
+#endif
+
+#ifndef VST_SUPPORT
+#define VST_SUPPORT
+/* Comment out the above line to build Mixbus without VST support */
+#endif
+
+#ifndef JACK_32_64
+#define JACK_32_64
+/* Shouldn't really be needed but make sure that any structs we
+ obtain from libjack will have 1-byte packing alignment where
+ necessary (belt & braces approach to be on the safe side) */
+#endif
+
+#ifdef _DEBUG
+#define _SECURE_SCL 1
+#define _HAS_ITERATOR_DEBUGGING 1
+/* #define to zero for a more conventional Debug build */
+#endif
+
+#ifndef __midl
+#if defined(_DEBUG) || defined (DEBUG)
+/* Experimental - link to the lowest DebugCRT so we can run on another system */
+#define _SXS_ASSEMBLY_VERSION "8.0.50727.42"
+#else
+#define _SXS_ASSEMBLY_VERSION "8.0.50727.6195"
+#endif
+#define _CRT_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
+#define _MFC_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
+#define _ATL_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+__declspec(selectany) int _forceCRTManifest;
+__declspec(selectany) int _forceMFCManifest;
+__declspec(selectany) int _forceAtlDllManifest;
+__declspec(selectany) int _forceCRTManifestRTM;
+__declspec(selectany) int _forceMFCManifestRTM;
+__declspec(selectany) int _forceAtlDllManifestRTM;
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/* 'stdint.h' conflicts with various other libraries so
+ let's #include stdint.h first to ensure one consistent
+ implementation for commonly used integer types. */
+#include <stdint.h>
+
+#if defined(_MSC_VER) && !defined(__MINGW__) && !defined(__MINGW32__)
+#if (INCLUDE_ARDOUR_MISCELLANEOUS)
+#include <ardourext/misc.h>
+#endif
+#endif
+
+#endif /*_TARGETSXS_H_*/
--- /dev/null
+#ifndef _WINX_SYS_TIME_H_
+#define _WINX_SYS_TIME_H_
+
+#define WIN32_LEAN_AND_MEAN /* This line found to be needed by JE - 18-08-2013. Line was formerly. . . #include <features.h> */
+#include <WinSock2.h> /* gets 'struct timeval' - Changed by JE - 23-07-2013. Was formerly. . . #include <WinSock.h> */
+
+#ifdef _TIMEVAL_DEFINED
+# define _STRUCT_TIMEVAL 1
+#endif /* _TIMEVAL_DEFINED */
+//#include <bits/types.h>
+#define __need_time_t
+#include <time.h>
+#define __need_timeval
+//#include <bits/time.h>
+
+#ifdef _TIMEVAL_DEFINED /* also in winsock[2].h */
+# undef __TIMEVAL__
+# define __TIMEVAL__ 1
+# undef _STRUCT_TIMEVAL
+# define _STRUCT_TIMEVAL 1
+#endif /* _TIMEVAL_DEFINED */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __USE_GNU
+/* Macros for converting between `struct timeval' and `struct timespec'. */
+# define TIMEVAL_TO_TIMESPEC(tv, ts) { \
+ (ts)->tv_sec = (tv)->tv_sec; \
+ (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+}
+# define TIMESPEC_TO_TIMEVAL(tv, ts) { \
+ (tv)->tv_sec = (ts)->tv_sec; \
+ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
+}
+#endif
+
+#ifdef __USE_BSD
+/* Structure crudely representing a timezone.
+ This is obsolete and should never be used. */
+struct timezone
+ {
+ int tz_minuteswest; /* Minutes west of GMT. */
+ int tz_dsttime; /* Nonzero if DST is ever in effect. */
+ };
+
+typedef struct timezone *__restrict __timezone_ptr_t;
+#else
+typedef void *__restrict __timezone_ptr_t;
+#endif
+
+/* Get the current time of day and timezone information,
+ putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
+ Returns 0 on success, -1 on errors.
+ NOTE: This form of timezone information is obsolete.
+ Use the functions and variables declared in <time.h> instead. */
+extern int gettimeofday (struct timeval *__restrict __tv,
+ __timezone_ptr_t __tz) __THROW;
+
+extern int getntptimeofday (struct timespec *__restrict __tp,
+ __timezone_ptr_t __tz) __THROW;
+
+#ifdef __USE_BSD
+/* Set the current time of day and timezone information.
+ This call is restricted to the super-user. */
+extern int settimeofday (__const struct timeval *__tv,
+ __const struct timezone *__tz) __THROW;
+extern int setntptimeofday (__const struct timespec *__tp,
+ __const struct timezone *__tz) __THROW;
+#endif
+
+///* Values for the first argument to `getitimer' and `setitimer'. */
+//enum __itimer_which
+// {
+// /* Timers run in real time. */
+// ITIMER_REAL = 0,
+//#define ITIMER_REAL ITIMER_REAL
+// /* Timers run only when the process is executing. */
+// ITIMER_VIRTUAL = 1,
+//#define ITIMER_VIRTUAL ITIMER_VIRTUAL
+// /* Timers run when the process is executing and when
+// the system is executing on behalf of the process. */
+// ITIMER_PROF = 2
+//#define ITIMER_PROF ITIMER_PROF
+// };
+
+/* Type of the second argument to `getitimer' and
+ the second and third arguments `setitimer'. */
+struct itimerval
+ {
+ /* Value to put into `it_value' when the timer expires. */
+ struct timeval it_interval;
+ /* Time to the next timer expiration. */
+ struct timeval it_value;
+ };
+
+#if defined __USE_GNU && !defined __cplusplus
+/* Use the nicer parameter type only in GNU mode and not for C++ since the
+ strict C++ rules prevent the automatic promotion. */
+typedef enum __itimer_which __itimer_which_t;
+#else
+typedef int __itimer_which_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_WINX_SYS_TIMEX_H_*/
--- /dev/null
+/*
+** Emtpy file to prevent Win32 compiler from complaining that the
+** file doesn't exist.
+*/
--- /dev/null
+
+Fedora Packages are installed via $ yum install foobar
+
+wine, needed to run some tests during the configure process
+
+mingw32-gcc
+
+mingw32-libogg
+
+mingw32-flac not in repo <- requires libogg
+
+mingw32-libvorbis
+
+mingw32-libsndfile not in repo <- requires flac, vorbis
+mingw32-libsamplerate not in repo <- requires sndfile for examples?
+
+mingw32-gtkmm24, this will pull in all the gtk+ deps etc
+
+mingw32-gtk2-engines not in repo <- provides clearlooks
+
+mingw32-libglade2, required for gnomecanvas
+
+mingw32-libart_lgpl not in repo
+mingw32-libgnomecanvas not in repo <- requires libart, libglade2
+mingw32-libgnomecanvasmm not in repo <- requires
+
+mingw32-portaudio not in repo
+
+mingw32-jack-audio-connection-kit not in repo
+
+mingw32-fftw not in repo
+
+mingw32-curl
+
+Optional
+
+mingw32-cppunit, if tests enabled
+mingw32-gdb, for debugging
+
+qemu-kvm to run virt images
+
--- /dev/null
+Building Ardour for Windows
+
+The windows build is compiled and tested with the MinGW compiler that is
+packaged in Fedora, Currently using Fedora 16. There are many cross compiled
+"mingw" libraries that Ardour requires that are also available on Fedora but
+not all are yet.
+
+
+Prerequisites
+
+Follow instructions in Fedora-16.txt to build and/or install the required
+packages.
+
+
+Configuring
+
+After all the necessary packages are installed the next step is to call
+one of the configure scripts configure-debug.sh or configure-release.sh.
+
+The configure-debug.sh script will enable debugging support and install
+the tests to the package directory. It will also mean the GDB debugger
+is packaged.
+
+The configure-release.sh is intended for releases only, none of the tests
+will be built and all the binaries will be optimized and stripped.
+
+These scripts both source the mingw-env.sh script to setup the appropriate
+environment variables and then call waf with a specific set of parameters
+that are appropriate to configure for the windows build.
+
+
+Building
+
+After the build is configured the waf.sh script is used to build the Ardour
+application and all necessary libraries. The waf.sh script is not strictly
+needed, it just saves having to change working directories.
+
+
+Packaging
+
+When the build is successful the package.sh script will call waf install
+and then move some of the installed files to appropriate locations for a
+windows executable. This could probably be done in the waf scripts specifically
+for the windows build but I felt it simpler to do it in the packaging script
+for now.
+
+The packaging script then copies the JACK deamon and all the required mingw
+shared libraries from the host system into the packaging directory. The
+shared libraries or dll's are placed in the same directory as the Ardour
+executable so they are found at runtime.
+
+Once the package.sh script has been run then the package directory located
+in the Ardour source root directory will contain everything necessary to run
+the Ardour executable.
+
+The make-installer.sh script is only really relevant when configure-release.sh
+has been used to configure the build. The script creates a basic and little
+tested windows installer for Ardour using the Nullsoft Scriptable Installer
+System(NSIS).
+
+
+Running
+
+The Ardour windows binary is intended to be run and tested on windows. Testing
+is mainly performed using Windows XP, but should work on Vista/7. It is only
+a 32bit binary at the moment but that may change with mingw64.
+
+The binary does not run successfully under WINE but that may change with updates
+and or bug fixes.
+
+When running Ardour for debugging purposes it is best to start the jack server
+in a separate terminal(Command Prompt) before starting Ardour so that they are
+not both writing to the same terminal. This will probably be fixed at some point
+so when jackd is started by Ardour the output is redirected etc.
+
+The cptovm.sh and startvm.sh scripts are intended for testing Ardour in a
+Windows XP virt image and may need to be altered to be used successfully.
+
+
+Testing
+
+When configured for debugging there are a number of test programs(prefixed with
+test_) included in the package.
+
+
+Debugging
+
+Ardour has some verbose logging/debugging output that can be useful that is used
+with the -D option.
+
+When configured for debugging the package contains gdb along with a .gdbinit
+file to automatically set the source directory so that the "list" gdb command
+will show the source code corresponding to the current stack frame.
+
+Use break `Somenamespace::somepartialsymbolname + tab to list symbols, then remove
+` to set break. If you press tab with when there are thousands of possible
+matching symbols be prepared to wait a long time(this can also cause gdb to use a
+lot of memory).
+
+For reasons I've yet to determine many symbols are not accessible so the best way
+to set a breakpoint is by using filename and line number.
+
+e.g (gdb) break audiosource.cc:976
+
+but this seems to only work after running Ardour at least once.
+
+They are a number of glib debugging options see
+
+http://developer.gnome.org/glib/2.30/glib-running.html
+
+use $ set G_DEBUG=fatal_warnings to get backtrace
+
--- /dev/null
+#!Nsis Installer Command Script
+#
+# This is an NSIS Installer Command Script generated automatically
+# by the Fedora nsiswrapper program. For more information see:
+#
+# http://fedoraproject.org/wiki/MinGW
+#
+# To build an installer from the script you would normally do:
+#
+# makensis this_script
+#
+# which will generate the output file 'installer.exe' which is a Windows
+# installer containing your program.
+
+SetCompressor /SOLID lzma
+SetCompressorDictSize 32
+
+!include MUI.nsh
+
+!define MUI_ABORTWARNING
+!define MUI_ICON ..\icons\icon\ardour.ico
+!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
+;!define MUI_HEADERIMAGE
+;!define MUI_HEADERIMAGE_BITMAP header.bmp
+;!define MUI_WELCOMEFINISHPAGE_BITMAP welcomefinish.bmp
+;!define MUI_COMPONENTSPAGE_SMALLDESC
+
+; Installer pages
+!insertmacro MUI_PAGE_WELCOME
+
+LicenseForceSelection off
+
+!define MUI_LICENSEPAGE_BUTTON "$(^NextBtn)"
+!define MUI_LICENSEPAGE_TEXT_BOTTOM "$(LICENSE_BOTTOM_TEXT)"
+!insertmacro MUI_PAGE_LICENSE ..\COPYING
+
+!insertmacro MUI_PAGE_DIRECTORY
+
+!insertmacro MUI_PAGE_INSTFILES
+
+!define MUI_FINISHPAGE_RUN "$INSTDIR\Ardour-3.0.exe"
+!insertmacro MUI_PAGE_FINISH
+
+; Uninstaller pages
+!insertmacro MUI_UNPAGE_CONFIRM
+
+!insertmacro MUI_UNPAGE_INSTFILES
+ShowUninstDetails hide
+!insertmacro MUI_UNPAGE_FINISH
+
+!insertmacro MUI_LANGUAGE "English"
+
+; Product definitions
+;!define DUMMYINSTALL ; Define this to make it build quickly, not including any of the files or code in the sections, for quick testing of features of the installer and development thereof.
+!define INSTDIR_KEY "SOFTWARE\Ardour-3.0"
+
+; Product Information
+Name "Ardour-3.0"
+OutFile "Ardour-3.0-Setup.exe"
+InstallDir "$PROGRAMFILES\Ardour"
+InstallDirRegKey HKLM "${INSTDIR_KEY}" "Install_Dir"
+
+
+ComponentText "Select which optional components you want to install."
+
+DirText "Please select the installation folder."
+
+Section "Ardour-3.0"
+!ifndef DUMMYINSTALL
+ SectionIn RO
+
+ SetOutPath $INSTDIR
+ File ardour-3.0.exe
+ File *.dll
+ File jack*.exe
+ File ardour.ico
+ File /r etc
+ File /r jack
+ File /r lib
+ File /r share
+
+!endif
+SectionEnd
+
+Section "Start Menu Shortcuts"
+!ifndef DUMMY_INSTALL
+ CreateDirectory "$SMPROGRAMS\Ardour-3.0"
+ CreateShortCut "$SMPROGRAMS\Ardour-3.0\Uninstall Ardour-3.0.lnk" "$INSTDIR\Uninstall Ardour-3.0.exe" "" "$INSTDIR\Uninstall Ardour-3.0.exe" 0
+ CreateShortCut "$SMPROGRAMS\Ardour-3.0\ardour-3.0.exe.lnk" "$INSTDIR\.\ardour-3.0.exe" "" "$INSTDIR\ardour.ico" 0
+!endif
+SectionEnd
+
+Section "Desktop Icons"
+!ifndef DUMMY_INSTALL
+ CreateShortCut "$DESKTOP\Ardour-3.0.exe.lnk" "$INSTDIR\ardour-3.0.exe" "" "$INSTDIR\ardour.ico"
+!endif
+SectionEnd
+
+Section "Uninstall"
+!ifndef DUMMY_INSTALL
+ Delete /rebootok "$DESKTOP\ardour-3.0.exe.lnk"
+ Delete /rebootok "$SMPROGRAMS\Ardour-3.0\ardour-3.0.exe.lnk"
+ Delete /rebootok "$SMPROGRAMS\Ardour-3.0\Uninstall Ardour-3.0.lnk"
+ RMDir "$SMPROGRAMS\Ardour-3.0"
+
+ ;RMDir "$INSTDIR\."
+ Delete /rebootok "$INSTDIR\ardour-3.0.exe"
+ Delete /rebootok "$INSTDIR\jack*.exe"
+ Delete /rebootok "$INSTDIR\*.dll"
+ Delete /rebootok "$INSTDIR\ardour.ico"
+ RMDir /r "$INSTDIR\etc"
+ RMDir /r "$INSTDIR\jack"
+ RMDir /r "$INSTDIR\lib"
+ RMDir /r "$INSTDIR\share"
+ RMDir "$INSTDIR"
+!endif
+SectionEnd
+
+Section -post
+!ifndef DUMMY_INSTALL
+ WriteUninstaller "$INSTDIR\Uninstall Ardour-3.0.exe"
+!endif
+SectionEnd
--- /dev/null
+#!/bin/bash
+
+. mingw-env.sh
+
+rm -rf $BUILD_DIR
--- /dev/null
+#!/bin/bash
+
+. ./mingw-env.sh
+
+. ./print-env.sh
+
+cd $BASE || exit 1
+./waf configure --prefix="/" --bindir="/" --configdir="/share" --noconfirm --no-lv2 --test --single-tests --dist-target=mingw "$@"
--- /dev/null
+#!/bin/bash
+
+. ./mingw-env.sh
+
+. ./print-env.sh
+
+cd $BASE || exit 1
+./waf configure --prefix="/" --bindir="/" --configdir="/share" --optimize --noconfirm --no-lv2 --dist-target=mingw "$@"
--- /dev/null
+#!/bin/bash
+
+. ./mingw-env.sh
+
+TMP_DIR=tmp
+LOOP_DEV=/dev/loop4
+
+cd $BASE || exit 1
+
+if [ ! -d $TMP_DIR ]; then
+ echo "Creating temp directory to mount vm image ..."
+ mkdir $TMP_DIR || exit 1
+fi
+
+echo "mounting vm image as loopback device ..."
+
+sudo mount -o loop=$LOOP_DEV,offset=32256 $VIRT_IMAGE_PATH $TMP_DIR || exit 1
+
+if [ -d $TMP_DIR/$PACKAGE_DIR ]; then
+ echo "Removing old copy of $PACKAGE_DIR from vm image ..."
+ rm -rf $TMP_DIR/$PACKAGE_DIR || exit 1
+fi
+
+echo "Copying $PACKAGE_DIR to vm image ..."
+cp -r $PACKAGE_DIR $TMP_DIR || exit 1
+
+if [ "$1" == "--data" ]; then
+ DATA_DIR=data
+
+ if [ -d $TMP_DIR/$DATA_DIR ]; then
+ echo "Removing old copy of $DATA_DIR from vm image ..."
+ rm -rf $TMP_DIR/$DATA_DIR || exit 1
+ fi
+
+ echo "Copying $DATA_DIR to vm image ..."
+ cp -r $DATA_DIR $TMP_DIR || exit 1
+fi
+
+
+# in case mount is busy
+sleep 2
+
+echo "Unmounting vm image ..."
+
+sudo umount -d tmp
+
+echo "Removing temp directory used to mount vm image ..."
+rm -rf $TMP_DIR || exit 1
+
+if sudo losetup $LOOP_DEV; then
+ echo "sleeping for 10 seconds and trying again ..."
+ sleep 10
+ if sudo losetup -d $LOOP_DEV; then
+ echo "Unmounted loopback device successfully"
+ exit 0
+ else:
+ echo "Unmounting loopback device unsuccessful, you will need to use losetup -d to unmount device"
+ exit 1
+ fi
+fi
+
+exit 0
--- /dev/null
+echo dir src/gtk2_ardour \n
+ dir src/gtk2_ardour
--- /dev/null
+# GdkPixbuf Image Loader Modules file
+# Automatically generated file, do not edit
+# Created by gdk-pixbuf-query-loaders.exe from gdk-pixbuf-2.21.7
+#
+# LoaderDir = Z:\usr\i686-pc-mingw32\sys-root\mingw/lib/gdk-pixbuf-2.0/2.10.0/loaders
+#
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.dll"
+"png" 5 "gdk-pixbuf" "The PNG image format" "LGPL"
+"image/png" ""
+"png" ""
+"\211PNG\r\n\032\n" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-xpm.dll"
+"xpm" 4 "gdk-pixbuf" "The XPM image format" "LGPL"
+"image/x-xpixmap" ""
+"xpm" ""
+"/* XPM */" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-bmp.dll"
+"bmp" 5 "gdk-pixbuf" "Het BMP-bestandsformaat" "LGPL"
+"image/bmp" "image/x-bmp" "image/x-MS-bmp" ""
+"bmp" ""
+"BM" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-tiff.dll"
+"tiff" 5 "gdk-pixbuf" "The TIFF image format" "LGPL"
+"image/tiff" ""
+"tiff" "tif" ""
+"MM *" " z " 100
+"II* " " z" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-pcx.dll"
+"pcx" 4 "gdk-pixbuf" "The PCX image format" "LGPL"
+"image/x-pcx" ""
+"pcx" ""
+"\n \001" "" 100
+"\n\002\001" "" 100
+"\n\003\001" "" 100
+"\n\004\001" "" 100
+"\n\005\001" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-wmf.dll"
+"wmf" 4 "gdk-pixbuf" "Het WMF-bestandsformaat" "LGPL"
+"image/x-wmf" ""
+"wmf" "apm" ""
+"\327\315\306\232" "" 100
+"\001" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ras.dll"
+"ras" 4 "gdk-pixbuf" "The Sun raster image format" "LGPL"
+"image/x-cmu-raster" "image/x-sun-raster" ""
+"ras" ""
+"Y\246j\225" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-ico.dll"
+"ico" 4 "gdk-pixbuf" "Het ICO-bestandsformaat" "LGPL"
+"image/x-icon" "image/x-ico" ""
+"ico" "cur" ""
+" \001 " "zz znz" 100
+" \002 " "zz znz" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-wbmp.dll"
+"wbmp" 4 "gdk-pixbuf" "The WBMP image format" "LGPL"
+"image/vnd.wap.wbmp" ""
+"wbmp" ""
+" " "zz" 1
+" `" "z " 1
+" @" "z " 1
+" " "z " 1
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-pnm.dll"
+"pnm" 4 "gdk-pixbuf" "The PNM/PBM/PGM/PPM image format family" "LGPL"
+"image/x-portable-anymap" "image/x-portable-bitmap" "image/x-portable-graymap" "image/x-portable-pixmap" ""
+"pnm" "pbm" "pgm" "ppm" ""
+"P1" "" 100
+"P2" "" 100
+"P3" "" 100
+"P4" "" 100
+"P5" "" 100
+"P6" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-ani.dll"
+"ani" 4 "gdk-pixbuf" "The ANI image format" "LGPL"
+"application/x-navi-animation" ""
+"ani" ""
+"RIFF ACON" " xxxx " 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-qtif.dll"
+"qtif" 4 "gdk-pixbuf" "The QTIF image format" "LGPL"
+"image/x-quicktime" "image/qtif" ""
+"qtif" "qif" ""
+"abcdidsc" "xxxx " 100
+"abcdidat" "xxxx " 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-xbm.dll"
+"xbm" 4 "gdk-pixbuf" "The XBM image format" "LGPL"
+"image/x-xbitmap" ""
+"xbm" ""
+"#define " "" 100
+"/*" "" 50
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-icns.dll"
+"icns" 4 "gdk-pixbuf" "The ICNS image format" "GPL"
+"image/x-icns" ""
+"icns" ""
+"icns" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-jasper.dll"
+"jpeg2000" 4 "gdk-pixbuf" "The JPEG 2000 image format" "LGPL"
+"image/jp2" "image/jpeg2000" "image/jpx" ""
+"jp2" "jpc" "jpx" "j2k" "jpf" ""
+" jP" "!!!! " 100
+"\377O\377Q" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-jpeg.dll"
+"jpeg" 5 "gdk-pixbuf" "Het JPEG-bestandsformaat" "LGPL"
+"image/jpeg" ""
+"jpeg" "jpe" "jpg" ""
+"\377\330" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-gif.dll"
+"gif" 5 "gdk-pixbuf" "Het GIF-bestandsformaat" "LGPL"
+"image/gif" ""
+"gif" ""
+"GIF8" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-gdip-emf.dll"
+"emf" 4 "gdk-pixbuf" "Het EMF-bestandsformaat" "LGPL"
+"application/emf" "application/x-emf" "image/x-emf" "image/x-mgx-emf" ""
+"emf" ""
+"\001" "" 100
+
+"lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-tga.dll"
+"tga" 4 "gdk-pixbuf" "The Targa image format" "LGPL"
+"image/x-tga" ""
+"tga" "targa" ""
+" \001\001" "x " 100
+" \001\t" "x " 100
+" \002" "xz " 99
+" \003" "xz " 100
+" \n" "xz " 100
+" \013" "xz " 100
+
+
--- /dev/null
+#!/bin/bash
+
+. ./mingw-env.sh
+
+cd $BASE || exit 1
+
+if test ! -d $PACKAGE_DIR; then
+ echo "Win32 package directory does not exist"
+ exit 1
+fi
+
+cp $TOOLS_DIR/ardour.nsi $PACKAGE_DIR || exit 1
+cp $BASE/icons/icon/ardour.ico $PACKAGE_DIR || exit 1
+
+cd $PACKAGE_DIR && makensis ardour.nsi
--- /dev/null
+#!/bin/bash
+
+BASE=$(readlink -f $0)
+BASE=$(dirname $BASE) # up one
+BASE=$(dirname $BASE) # up one more
+BASE=$(dirname $BASE) # up one more
+
+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=pkg-config
+export AR=$HOST-ar
+export RANLIB=$HOST-ranlib
+export CC=$HOST-gcc
+export CPP=$HOST-g++
+export CXX=$HOST-g++
+export AS=$HOST-as
+export LINK_CC=$HOST-gcc
+export LINK_CXX=$HOST-g++
+export WINRC=$HOST-windres
+export STRIP=$HOST-strip
+
+BUILD_DIR=$BASE/build
+BUILD_CACHE_FILE=$BUILD_DIR/c4che/_cache.py
+TOOLS_DIR=$BASE/tools/windows_packaging
+
+. ../define_versions.sh
+
+APPNAME=`grep -m 1 '^APPNAME' $BASE/wscript | awk '{print $3}' | sed "s/'//g"`
+
+# These are only relevant after a build
+if test -f $BUILD_CACHE_FILE
+then
+ # Figure out the Build Type
+ if grep -q "DEBUG = True" $BUILD_CACHE_FILE; then
+ DEBUG=1
+ PACKAGE_DIR="$APPNAME-${version}-win32-dbg"
+ else
+ PACKAGE_DIR="$APPNAME-${version}-win32"
+ fi
+
+ if grep -q "BUILD_TESTS = True" $BUILD_CACHE_FILE; then
+ WITH_TESTS=1
+ fi
+
+ ARDOUR_DATA_DIR=$PACKAGE_DIR/share/ardour3
+fi
+
+# put this somewhere better...
+VIRT_IMAGE_PATH=$HOME/Data/virt-images/winxp.raw
--- /dev/null
+#!/bin/bash
+
+. ./mingw-env.sh
+
+. ./print-env.sh
+
+cd $BASE || exit 1
+
+if ! test -f $BUILD_CACHE_FILE; then
+ echo "ERROR: $APPNAME is not configured and built yet..."
+ exit 1
+fi
+
+if [ -d $PACKAGE_DIR ]; then
+ echo "Removing old package directory structure ..."
+ rm -rf $PACKAGE_DIR || exit 1
+fi
+
+./waf --destdir=$PACKAGE_DIR install || exit 1
+
+echo "Moving Ardour dll's and executable to $PACKAGE_DIR ..."
+
+mv $PACKAGE_DIR/lib/ardour3/*.dll $PACKAGE_DIR || exit 1
+mv $PACKAGE_DIR/lib/ardour3/*.exe $PACKAGE_DIR || exit 1
+
+echo "Deleting import libs ..."
+
+rm $PACKAGE_DIR/lib/*dll.a
+
+# delete sh script
+rm $PACKAGE_DIR/ardour3
+
+if test x$WITH_TESTS != x ; then
+ echo "Copying tests and test data to $PACKAGE_DIR ..."
+ cp $BUILD_DIR/libs/pbd/run-tests.exe $PACKAGE_DIR/pbd-run-tests.exe
+ cp -r $BASE/libs/pbd/test $PACKAGE_DIR/pbd_testdata
+
+ cp $BUILD_DIR/libs/evoral/run-tests.exe $PACKAGE_DIR/evoral-run-tests.exe
+ mkdir -p $PACKAGE_DIR/test/testdata
+ cp -r $BASE/libs/evoral/test/testdata/TakeFive.mid $PACKAGE_DIR/test/testdata
+
+ cp -r $BASE/libs/ardour/test/data $PACKAGE_DIR/ardour_testdata
+fi
+
+echo "Copying mingw config files to $PACKAGE_DIR ..."
+# just copy it all for now
+cp -r $MINGW_ROOT/etc $PACKAGE_DIR
+
+cp -r $MINGW_ROOT/lib/gtk-2.0 $PACKAGE_DIR/lib
+cp -r $MINGW_ROOT/lib/gdk-pixbuf-2.0 $PACKAGE_DIR/lib
+cp $TOOLS_DIR/loaders.cache $PACKAGE_DIR/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
+
+mkdir -p $PACKAGE_DIR/lib/pango/1.6.0/modules
+cp -r $MINGW_ROOT/lib/pango/1.6.0/modules/*.dll $PACKAGE_DIR/lib/pango/1.6.0/modules
+cp $TOOLS_DIR/pango.modules $PACKAGE_DIR/etc/pango
+
+DLLS='
+jack-0.dll
+jackserver-0.dll
+libart_lgpl_2-2.dll
+libatk-1.0-0.dll
+libatkmm-1.6-1.dll
+libbz2-1.dll
+libcairo-2.dll
+libcairo-gobject-2.dll
+libcairomm-1.0-1.dll
+libcairo-script-interpreter-2.dll
+libcppunit-1-12-1.dll
+libcrypto-10.dll
+libcurl-4.dll
+libexpat-1.dll
+libfftw3-3.dll
+libfftw3f-3.dll
+libfontconfig-1.dll
+libfreetype-6.dll
+libgailutil-18.dll
+libgcc_s_sjlj-1.dll
+libgdkmm-2.4-1.dll
+libgdk_pixbuf-2.0-0.dll
+libgdk-win32-2.0-0.dll
+libgio-2.0-0.dll
+libgiomm-2.4-1.dll
+libglib-2.0-0.dll
+libglibmm-2.4-1.dll
+libglibmm_generate_extra_defs-2.4-1.dll
+libgmodule-2.0-0.dll
+libgnomecanvas-2-0.dll
+libgnomecanvasmm-2.6-1.dll
+libgnurx-0.dll
+libgobject-2.0-0.dll
+libgthread-2.0-0.dll
+libgtkmm-2.4-1.dll
+libgtk-win32-2.0-0.dll
+libharfbuzz-0.dll
+libiconv-2.dll
+iconv.dll
+libFLAC-8.dll
+libogg-0.dll
+libvorbis-0.dll
+libvorbisenc-2.dll
+libffi-6.dll
+libidn-11.dll
+libintl-8.dll
+liblo-7.dll
+libpango-1.0-0.dll
+libpangocairo-1.0-0.dll
+libpangoft2-1.0-0.dll
+libpangomm-1.4-1.dll
+libpangowin32-1.0-0.dll
+libpixman-1-0.dll
+libpng15-15.dll
+libsamplerate-0.dll
+libsigc-2.0-0.dll
+libsndfile-1.dll
+libssh2-1.dll
+libssl-10.dll
+libstdc++-6.dll
+libxml2-2.dll
+pthreadGC2.dll
+zlib1.dll
+'
+
+echo "Copying mingw shared libraries to $PACKAGE_DIR ..."
+
+for i in $DLLS;
+do
+cp $MINGW_ROOT/bin/$i $PACKAGE_DIR
+done
+
+echo "Copying JACK server and drivers to $PACKAGE_DIR ..."
+
+cp $MINGW_ROOT/bin/jackd.exe $PACKAGE_DIR
+cp -r $MINGW_ROOT/bin/jack $PACKAGE_DIR
+cp $MINGW_ROOT/bin/libportaudio-2.dll $PACKAGE_DIR
+
+SRC_DIRS='
+libs/ardour
+libs/pbd
+libs/gtkmm2ext
+libs/midi++2
+libs/evoral
+libs/panners
+libs/timecode
+libs/audiographer
+'
+
+if test x$DEBUG != x ; then
+
+ PACKAGE_SRC_DIR=$PACKAGE_DIR/src
+ echo "Copying source files to $PACKAGE_SRC_DIR ..."
+ mkdir -p $PACKAGE_SRC_DIR/libs
+ cp -r $BASE/gtk2_ardour $PACKAGE_SRC_DIR
+ for i in $SRC_DIRS;
+ do
+ cp -r -p $BASE/$i $PACKAGE_SRC_DIR/libs
+ done
+
+ echo "Copying JACK utility programs to $PACKAGE_DIR ..."
+ cp $MINGW_ROOT/bin/jack_*.exe $PACKAGE_DIR
+
+ echo "Copying any debug files to $PACKAGE_DIR ..."
+ cp $MINGW_ROOT/bin/*.debug $PACKAGE_DIR
+
+ echo "Copying gdb to $PACKAGE_DIR ..."
+ cp $MINGW_ROOT/bin/gdb.exe $PACKAGE_DIR
+
+ echo "Copying .gdbinit to $PACKAGE_DIR ..."
+ cp $TOOLS_DIR/gdbinit $PACKAGE_DIR/.gdbinit
+
+ echo "Copying Gtk demo to $PACKAGE_DIR ..."
+ cp $MINGW_ROOT/bin/gtk-demo.exe $PACKAGE_DIR
+else
+ echo "Optimized build Stripping executable ..."
+ $STRIP $PACKAGE_DIR/ardour-3.0.exe
+ echo "Stripping libraries ..."
+ find $PACKAGE_DIR -type f -name "*.dll*" | xargs $STRIP
+fi
+
+if [ "$1" == "--tarball" ]; then
+ echo "Creating tarball from $PACKAGE_DIR ..."
+ cd $BASE || exit 1
+ tar -cvJf $PACKAGE_DIR.tar.xz $PACKAGE_DIR
+fi
+
+if [ "$1" == "--zip" ]; then
+ echo "Creating zip file from $PACKAGE_DIR ..."
+ cd $BASE || exit 1
+ zip -r $PACKAGE_DIR.zip $PACKAGE_DIR
+fi
--- /dev/null
+# Pango Modules file
+# Automatically generated file, do not edit
+#
+# 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:*
--- /dev/null
+echo "Build Environment Settings...."
+echo " "
+echo " "
+echo "HOST : $HOST"
+echo "MINGW_ROOT : $MINGW_ROOT"
+echo "PKG_CONFIG_PREFIX : $PKG_CONFIG_PREFIX"
+echo "PKG_CONFIG_LIBDIR : $PKG_CONFIG_LIBDIR"
+echo "PKGCONFIG : $PKGCONFIG"
+echo "AR : $AR"
+echo "RANLIB : $RANLIB"
+echo "CC : $CC"
+echo "CPP : $CPP"
+echo "CXX : $CXX"
+echo "AS : $AS"
+echo "LINK_CC : $LINK_CC"
+echo "LINK_CXX : $LINK_CXX"
+echo "WINRC : $WINRC"
+echo "STRIP : $STRIP"
+echo " "
+echo " "
+echo "Path Environment Settings...."
+echo " "
+echo " "
+echo "BASE : $BASE"
+echo "BUILD_DIR : $BUILD_DIR"
+echo "BUILD_CACHE_FILE : $BUILD_CACHE_FILE"
+echo "TOOLS_DIR : $TOOLS_DIR"
+echo "PACKAGE_DIR : $PACKAGE_DIR"
+echo " "
+echo " "
+echo "Config Environment Settings...."
+echo " "
+echo " "
+echo "APPNAME : $APPNAME"
+echo "VERSION : $VERSION"
+echo "DEBUG : $DEBUG"
+echo "WITH_TESTS : $WITH_TESTS"
+echo "ARDOUR_DATA_DIR : $ARDOUR_DATA_DIR"
+echo " "
+echo " "
--- /dev/null
+#!/bin/bash
+
+. ./mingw-env.sh
+
+cd $BASE
+
+LIBS=$BUILD_DIR/libs
+
+export ARDOUR_PATH=$BASE/gtk2_ardour/icons:$BASE/gtk2_ardour/pixmaps:$BASE/build/default/gtk2_ardour:$BASE/gtk2_ardour:.
+export ARDOUR_SURFACES_PATH=$LIBS/surfaces/osc:$LIBS/surfaces/generic_midi:$LIBS/surfaces/tranzport:$LIBS/surfaces/powermate:$LIBS/surfaces/mackie
+export ARDOUR_PANNER_PATH=$LIBS/panners/2in2out:$LIBS/panners/1in2out:$LIBS/panners/vbap
+export ARDOUR_DATA_PATH=$BASE/gtk2_ardour:build/default/gtk2_ardour:.
+
+export VAMP_PATH=$LIBS/vamp-plugins${VAMP_PATH:+:$VAMP_PATH}
+
+export PBD_TEST_PATH=$BASE/libs/pbd/test/
+
+if test ! -d $PACKAGE_DIR; then
+ echo "Win32 package directory does not exist"
+ exit 1
+fi
+
+cd $PACKAGE_DIR
+
+
+if [ "$1" == "--run-tests" ]; then
+ if test x$WITH_TESTS != x ; then
+ echo "<<<<<<<<<<<<<<<<<< RUNNING LIBPBD TESTS >>>>>>>>>>>>>>>>>>>"
+ wine pbd-run-tests.exe
+ echo "<<<<<<<<<<<<<<<<<< RUNNING EVORAL TESTS >>>>>>>>>>>>>>>>>>>"
+ wine evoral-run-tests.exe
+ echo "<<<<<<<<<<<<<<<<<< RUNNING ARDOUR TESTS >>>>>>>>>>>>>>>>>>>"
+ wine ardour-run-tests.exe
+ else
+ echo "No tests to run ..."
+ fi
+else
+ wine ardour-3.0.exe
+fi
--- /dev/null
+#!/bin/bash
+. mingw-env.sh
+
+qemu-kvm -smp 2 -m 1536 -hda $VIRT_IMAGE_PATH -net nic -net user -vga std -soundhw all
--- /dev/null
+#!/bin/bash
+
+. ./mingw-env.sh
+
+cd $BASE || exit 1
+./waf "$@"
out = 'build'
children = [
- 'libs/pbd',
- 'libs/midi++2',
- 'libs/evoral',
+ # optionally external libraries
'libs/vamp-sdk',
'libs/qm-dsp',
'libs/vamp-plugins',
'libs/taglib',
'libs/libltc',
'libs/rubberband',
+ # core ardour libraries
+ 'libs/pbd',
+ 'libs/midi++2',
+ 'libs/evoral',
'libs/surfaces',
'libs/panners',
'libs/backends',
'libs/timecode',
'libs/ardour',
'libs/gtkmm2ext',
- 'libs/clearlooks-newer',
'libs/audiographer',
'libs/plugins/reasonablesynth.lv2',
'gtk2_ardour',
'export',
'midi_maps',
'mcp',
- 'patchfiles'
+ 'patchfiles',
]
i18n_children = [
'libs/gtkmm2ext',
]
-if sys.platform == 'linux2':
- children += [ 'tools/sanity_check' ]
- lxvst_default = True
-elif sys.platform == 'darwin':
- children += [ 'libs/appleutility' ]
- lxvst_default = False
-else:
- lxvst_default = False
-
# Version stuff
def fetch_gcc_version (CC):
debug_flags = [ '-pg' ]
if opt.backtrace:
- if platform != 'darwin' and not is_clang:
- debug_flags = [ '-rdynamic' ]
+ if opt.dist_target == 'auto':
+ if platform != 'darwin' and not is_clang:
+ debug_flags = [ '-rdynamic' ]
# Autodetect
if opt.dist_target == 'auto':
print("However, this is tricky and not recommended for beginners.")
sys.exit (-1)
- if opt.lxvst:
+ if conf.env['LXVST_SUPPORT'] == True:
if conf.env['build_target'] == 'x86_64':
conf.env.append_value('CXXFLAGS', "-DLXVST_64BIT")
else:
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')
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=True, 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)')
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('CFLAGS', '-DPLATFORM_WINDOWS')
+ conf.env.append_value('CFLAGS', '-DCOMPILER_MINGW')
+ conf.env.append_value('CXXFLAGS', '-DPLATFORM_WINDOWS')
+ conf.env.append_value('CXXFLAGS', '-DCOMPILER_MINGW')
+ 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
conf.env.append_value('CXXFLAGS', '-I' + Options.options.wine_include)
autowaf.check_header(conf, 'cxx', 'windows.h', mandatory = True)
if opts.lxvst:
- conf.define('LXVST_SUPPORT', 1)
- conf.env['LXVST_SUPPORT'] = True
+ if sys.platform == 'darwin':
+ conf.env['LXVST_SUPPORT'] = False
+ elif Options.options.dist_target == 'mingw':
+ conf.env['LXVST_SUPPORT'] = False
+ else:
+ conf.define('LXVST_SUPPORT', 1)
+ conf.env['LXVST_SUPPORT'] = True
conf.define('WINDOWS_KEY', opts.windows_key)
conf.env['PROGRAM_NAME'] = opts.program_name
if opts.rt_alloc_debug:
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)
write_config_text('C compiler flags', conf.env['CFLAGS'])
write_config_text('C++ compiler flags', conf.env['CXXFLAGS'])
- write_config_text('Linker flags', conf.env['LINKFLAGS'])
+ write_config_text('Linker flags', conf.env['LINKFLAGS'])
config_text.write ('";\n}\n')
config_text.close ()
# add directories that contain only headers, to workaround an issue with waf
- bld.path.find_dir ('libs/evoral/evoral')
if not bld.is_defined('USE_EXTERNAL_LIBS'):
bld.path.find_dir ('libs/vamp-sdk/vamp-sdk')
- bld.path.find_dir ('libs/surfaces/control_protocol/control_protocol')
- bld.path.find_dir ('libs/timecode/timecode')
- if not bld.is_defined('USE_EXTERNAL_LIBS'):
bld.path.find_dir ('libs/libltc/ltc')
bld.path.find_dir ('libs/rubberband/rubberband')
+ bld.path.find_dir ('libs/taglib/taglib')
+ bld.path.find_dir ('libs/evoral/evoral')
+ bld.path.find_dir ('libs/surfaces/control_protocol/control_protocol')
+ bld.path.find_dir ('libs/timecode/timecode')
bld.path.find_dir ('libs/gtkmm2ext/gtkmm2ext')
bld.path.find_dir ('libs/ardour/ardour')
- if not bld.is_defined('USE_EXTERNAL_LIBS'):
- bld.path.find_dir ('libs/taglib/taglib')
bld.path.find_dir ('libs/pbd/pbd')
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)